tdf#144694 In direct SQL dialog, activate options 'Run SQL command
[LibreOffice.git] / svx / source / svdraw / svdpagv.cxx
blob8b1f837a6301dc56158082207f4af4ff10f97dcc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/svdpagv.hxx>
21 #include <svx/svdpage.hxx>
22 #include <svx/svdview.hxx>
24 #include <svx/svdobj.hxx>
25 #include <svx/svdogrp.hxx>
26 #include <svx/svdtypes.hxx>
28 #include <svx/sdr/contact/viewobjectcontactredirector.hxx>
30 #include <algorithm>
32 #include <svx/sdrpagewindow.hxx>
33 #include <svx/sdrpaintwindow.hxx>
34 #include <comphelper/lok.hxx>
35 #include <comphelper/scopeguard.hxx>
36 #include <basegfx/range/b2irectangle.hxx>
37 #include <osl/diagnose.h>
39 using namespace ::com::sun::star;
41 // interface to SdrPageWindow
43 SdrPageWindow* SdrPageView::FindPageWindow(const SdrPaintWindow& rPaintWindow) const
45 for(auto & a : maPageWindows)
47 if(&(a->GetPaintWindow()) == &rPaintWindow)
49 return a.get();
53 return nullptr;
56 const SdrPageWindow* SdrPageView::FindPatchedPageWindow( const OutputDevice& _rOutDev ) const
58 for ( auto const & pPageWindow : maPageWindows )
60 const SdrPaintWindow& rPaintWindow( pPageWindow->GetOriginalPaintWindow() ? *pPageWindow->GetOriginalPaintWindow() : pPageWindow->GetPaintWindow() );
61 if ( &rPaintWindow.GetOutputDevice() == &_rOutDev )
63 return pPageWindow.get();
67 return nullptr;
70 SdrPageWindow* SdrPageView::FindPageWindow(const OutputDevice& rOutDev) const
72 for ( auto const & pPageWindow : maPageWindows )
74 if(&(pPageWindow->GetPaintWindow().GetOutputDevice()) == &rOutDev)
76 return pPageWindow.get();
80 return nullptr;
83 SdrPageWindow* SdrPageView::GetPageWindow(sal_uInt32 nIndex) const
85 return maPageWindows[nIndex].get();
88 SdrPageView::SdrPageView(SdrPage* pPage1, SdrView& rNewView)
89 : mrView(rNewView),
90 // col_auto color lets the view takes the default SvxColorConfig entry
91 maDocumentColor( COL_AUTO ),
92 maBackgroundColor( COL_AUTO ), // #i48367# also react on autocolor
93 mpPreparedPageWindow(nullptr) // #i72752#
95 mpPage = pPage1;
97 if(mpPage)
99 maPageOrigin.setX(mpPage->GetLeftBorder() );
100 maPageOrigin.setY(mpPage->GetUpperBorder() );
102 // For example, in the case of charts, there is a LayerAdmin, but it has no valid values. Therefore
103 // a solution like pLayerAdmin->getVisibleLayersODF(aLayerVisi) is not possible. So use the
104 // generic SetAll() for now.
105 m_aLayerVisi.SetAll();
106 m_aLayerPrn.SetAll();
108 mbHasMarked = false;
109 mbVisible = false;
110 m_pCurrentList = nullptr;
111 m_pCurrentGroup = nullptr;
112 SetCurrentGroupAndList(nullptr, mpPage);
114 for(sal_uInt32 a(0); a < rNewView.PaintWindowCount(); a++)
116 AddPaintWindowToPageView(*rNewView.GetPaintWindow(a));
120 SdrPageView::~SdrPageView()
124 void SdrPageView::AddPaintWindowToPageView(SdrPaintWindow& rPaintWindow)
126 if(!FindPageWindow(rPaintWindow))
128 maPageWindows.emplace_back(new SdrPageWindow(*this, rPaintWindow));
132 void SdrPageView::RemovePaintWindowFromPageView(SdrPaintWindow& rPaintWindow)
134 auto it = std::find_if(maPageWindows.begin(), maPageWindows.end(),
135 [&rPaintWindow](const std::unique_ptr<SdrPageWindow>& rpWindow) {
136 return &(rpWindow->GetPaintWindow()) == &rPaintWindow;
138 if (it != maPageWindows.end())
139 maPageWindows.erase(it);
142 css::uno::Reference< css::awt::XControlContainer > SdrPageView::GetControlContainer( const OutputDevice& _rDevice ) const
144 css::uno::Reference< css::awt::XControlContainer > xReturn;
145 const SdrPageWindow* pCandidate = FindPatchedPageWindow( _rDevice );
147 if ( pCandidate )
148 xReturn = pCandidate->GetControlContainer();
150 return xReturn;
153 void SdrPageView::ModelHasChanged()
155 if (GetCurrentGroup()!=nullptr) CheckCurrentGroup();
158 bool SdrPageView::IsReadOnly() const
160 return (nullptr == GetPage() || GetView().GetModel().IsReadOnly() || GetPage()->IsReadOnly() || GetObjList()->IsReadOnly());
163 void SdrPageView::Show()
165 if(!IsVisible())
167 mbVisible = true;
169 for(sal_uInt32 a(0); a < GetView().PaintWindowCount(); a++)
171 AddPaintWindowToPageView(*GetView().GetPaintWindow(a));
176 void SdrPageView::Hide()
178 if(IsVisible())
180 if (!comphelper::LibreOfficeKit::isActive())
182 InvalidateAllWin();
184 mbVisible = false;
185 maPageWindows.clear();
189 tools::Rectangle SdrPageView::GetPageRect() const
191 if (GetPage()==nullptr) return tools::Rectangle();
192 return tools::Rectangle(Point(),Size(GetPage()->GetWidth()+1,GetPage()->GetHeight()+1));
195 void SdrPageView::InvalidateAllWin()
197 if(IsVisible() && GetPage())
199 tools::Rectangle aRect(Point(0,0),Size(GetPage()->GetWidth()+1,GetPage()->GetHeight()+1));
200 aRect.Union(GetPage()->GetAllObjBoundRect());
201 GetView().InvalidateAllWin(aRect);
206 void SdrPageView::PrePaint()
208 const sal_uInt32 nCount(PageWindowCount());
210 for(sal_uInt32 a(0); a < nCount; a++)
212 SdrPageWindow* pCandidate = GetPageWindow(a);
214 if(pCandidate)
216 pCandidate->PrePaint();
221 void SdrPageView::CompleteRedraw(
222 SdrPaintWindow& rPaintWindow, const vcl::Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector )
224 if(!GetPage())
225 return;
227 SdrPageWindow* pPageWindow = FindPageWindow(rPaintWindow);
228 std::unique_ptr<SdrPageWindow> pTempPageWindow;
230 if(!pPageWindow)
232 // create temp PageWindow
233 pTempPageWindow.reset(new SdrPageWindow(*this, rPaintWindow));
234 pPageWindow = pTempPageWindow.get();
237 // do the redraw
238 pPageWindow->PrepareRedraw(rReg);
239 pPageWindow->RedrawAll(pRedirector);
243 // #i74769# use SdrPaintWindow directly
245 void SdrPageView::setPreparedPageWindow(SdrPageWindow* pKnownTarget)
247 // #i72752# remember prepared SdrPageWindow
248 mpPreparedPageWindow = pKnownTarget;
251 void SdrPageView::DrawLayer(SdrLayerID nID, OutputDevice* pGivenTarget,
252 sdr::contact::ViewObjectContactRedirector* pRedirector,
253 const tools::Rectangle& rRect, basegfx::B2IRectangle const*const pPageFrame)
255 if(!GetPage())
256 return;
258 if(pGivenTarget)
260 SdrPageWindow* pKnownTarget = FindPageWindow(*pGivenTarget);
262 if(pKnownTarget)
264 // paint known target
265 pKnownTarget->RedrawLayer(&nID, pRedirector, pPageFrame);
267 else
269 // #i72752# DrawLayer() uses an OutputDevice different from BeginDrawLayer. This happens
270 // e.g. when SW paints a single text line in text edit mode. Try to use it
271 SdrPageWindow* pPreparedTarget = mpPreparedPageWindow;
273 if(pPreparedTarget)
275 // if we have a prepared target, do not use a new SdrPageWindow since this
276 // works but is expensive. Just use a temporary PaintWindow
277 SdrPaintWindow aTemporaryPaintWindow(mrView, *pGivenTarget);
279 // Copy existing paint region to use the same as prepared in BeginDrawLayer
280 SdrPaintWindow& rExistingPaintWindow = pPreparedTarget->GetPaintWindow();
281 const vcl::Region& rExistingRegion = rExistingPaintWindow.GetRedrawRegion();
282 bool bUseRect(false);
283 if (!rRect.IsEmpty())
285 vcl::Region r(rExistingRegion);
286 r.Intersect(rRect);
287 // fdo#74435: FIXME: visibility check broken if empty
288 if (!r.IsEmpty())
289 bUseRect = true;
291 if (!bUseRect)
292 aTemporaryPaintWindow.SetRedrawRegion(rExistingRegion);
293 else
294 aTemporaryPaintWindow.SetRedrawRegion(vcl::Region(rRect));
296 // patch the ExistingPageWindow
297 auto pPreviousWindow = pPreparedTarget->patchPaintWindow(aTemporaryPaintWindow);
298 // unpatch window when leaving the scope
299 const ::comphelper::ScopeGuard aGuard(
300 [&pPreviousWindow, &pPreparedTarget]() { pPreparedTarget->unpatchPaintWindow(pPreviousWindow); } );
301 // redraw the layer
302 pPreparedTarget->RedrawLayer(&nID, pRedirector, pPageFrame);
304 else
306 OSL_FAIL("SdrPageView::DrawLayer: Creating temporary SdrPageWindow (ObjectContact), this should never be needed (!)");
308 // None of the known OutputDevices is the target of this paint, use
309 // a temporary SdrPageWindow for this Redraw.
310 SdrPaintWindow aTemporaryPaintWindow(mrView, *pGivenTarget);
311 SdrPageWindow aTemporaryPageWindow(*this, aTemporaryPaintWindow);
313 // #i72752#
314 // Copy existing paint region if other PageWindows exist, this was created by
315 // PrepareRedraw() from BeginDrawLayer(). Needs to be used e.g. when suddenly SW
316 // paints into an unknown device other than the view was created for (e.g. VirtualDevice)
317 if(PageWindowCount())
319 SdrPageWindow* pExistingPageWindow = GetPageWindow(0);
320 SdrPaintWindow& rExistingPaintWindow = pExistingPageWindow->GetPaintWindow();
321 const vcl::Region& rExistingRegion = rExistingPaintWindow.GetRedrawRegion();
322 aTemporaryPaintWindow.SetRedrawRegion(rExistingRegion);
325 aTemporaryPageWindow.RedrawLayer(&nID, pRedirector, nullptr);
329 else
331 // paint in all known windows
332 for(sal_uInt32 a(0); a < PageWindowCount(); a++)
334 SdrPageWindow* pTarget = GetPageWindow(a);
335 pTarget->RedrawLayer(&nID, pRedirector, nullptr);
340 void SdrPageView::SetDesignMode( bool _bDesignMode ) const
342 for ( sal_uInt32 i = 0; i < PageWindowCount(); ++i )
344 const SdrPageWindow& rPageViewWindow = *GetPageWindow(i);
345 rPageViewWindow.SetDesignMode( _bDesignMode );
350 void SdrPageView::DrawPageViewGrid(OutputDevice& rOut, const tools::Rectangle& rRect, Color aColor)
352 if (GetPage()==nullptr)
353 return;
355 tools::Long nx1=GetView().maGridBig.Width();
356 tools::Long nx2=GetView().maGridFin.Width();
357 tools::Long ny1=GetView().maGridBig.Height();
358 tools::Long ny2=GetView().maGridFin.Height();
360 if (nx1==0) nx1=nx2;
361 if (nx2==0) nx2=nx1;
362 if (ny1==0) ny1=ny2;
363 if (ny2==0) ny2=ny1;
364 if (nx1==0) { nx1=ny1; nx2=ny2; }
365 if (ny1==0) { ny1=nx1; ny2=nx2; }
366 if (nx1<0) nx1=-nx1;
367 if (nx2<0) nx2=-nx2;
368 if (ny1<0) ny1=-ny1;
369 if (ny2<0) ny2=-ny2;
371 if (nx1==0)
372 return;
374 // no more global output size, use window size instead to decide grid sizes
375 tools::Long nScreenWdt = rOut.GetOutputSizePixel().Width();
377 tools::Long nMinDotPix=2;
378 tools::Long nMinLinPix=4;
380 if (nScreenWdt>=1600)
382 nMinDotPix=4;
383 nMinLinPix=8;
385 else if (nScreenWdt>=1024)
387 nMinDotPix=3;
388 nMinLinPix=6;
390 else
391 { // e. g. 640x480
392 nMinDotPix=2;
393 nMinLinPix=4;
395 Size aMinDotDist(rOut.PixelToLogic(Size(nMinDotPix,nMinDotPix)));
396 Size aMinLinDist(rOut.PixelToLogic(Size(nMinLinPix,nMinLinPix)));
397 bool bHoriSolid=nx2<aMinDotDist.Width();
398 bool bVertSolid=ny2<aMinDotDist.Height();
399 // enlarge line offset (minimum 4 pixels)
400 // enlarge by: *2 *5 *10 *20 *50 *100 ...
401 int nTgl=0;
402 tools::Long nVal0=nx1;
403 while (nx1<aMinLinDist.Width())
405 tools::Long a=nx1;
407 if (nTgl==0) nx1*=2;
408 if (nTgl==1) nx1=nVal0*5; // => nx1*=2.5
409 if (nTgl==2) nx1*=2;
411 nVal0=a;
412 nTgl++; if (nTgl>=3) nTgl=0;
414 nTgl=0;
415 nVal0=ny1;
416 while (ny1<aMinLinDist.Height())
418 tools::Long a=ny1;
420 if (nTgl==0) ny1*=2;
421 if (nTgl==1) ny1=nVal0*5; // => ny1*=2.5
422 if (nTgl==2) ny1*=2;
424 nVal0=a;
425 nTgl++;
427 if (nTgl>=3) nTgl=0;
430 bool bHoriFine=nx2<nx1;
431 bool bVertFine=ny2<ny1;
432 bool bHoriLines=bHoriSolid || bHoriFine || !bVertFine;
433 bool bVertLines=bVertSolid || bVertFine;
435 Color aOriginalLineColor( rOut.GetLineColor() );
436 rOut.SetLineColor( aColor );
438 bool bMap0=rOut.IsMapModeEnabled();
440 tools::Long nWrX=0;
441 tools::Long nWrY=0;
442 Point aOrg(maPageOrigin);
443 tools::Long x1 = 0;
444 tools::Long x2 = 0;
445 if (GetPage()->GetWidth() < 0) // ScDrawPage of RTL sheet
447 x1 = GetPage()->GetWidth() + GetPage()->GetLeftBorder() + 1;
448 x2 = - GetPage()->GetRightBorder() - 1;
450 else
452 x1 = GetPage()->GetLeftBorder() + 1;
453 x2 = GetPage()->GetWidth() - GetPage()->GetRightBorder() - 1;
455 tools::Long y1 = GetPage()->GetUpperBorder() + 1;
456 tools::Long y2 = GetPage()->GetHeight() - GetPage()->GetLowerBorder() - 1;
457 const SdrPageGridFrameList* pFrames=GetPage()->GetGridFrameList(this,nullptr);
459 sal_uInt16 nGridPaintCnt=1;
460 if (pFrames!=nullptr) nGridPaintCnt=pFrames->GetCount();
461 for (sal_uInt16 nGridPaintNum=0; nGridPaintNum<nGridPaintCnt; nGridPaintNum++) {
462 if (pFrames!=nullptr) {
463 const SdrPageGridFrame& rGF=(*pFrames)[nGridPaintNum];
464 nWrX=rGF.GetPaperRect().Left();
465 nWrY=rGF.GetPaperRect().Top();
466 x1=rGF.GetUserArea().Left();
467 x2=rGF.GetUserArea().Right();
468 y1=rGF.GetUserArea().Top();
469 y2=rGF.GetUserArea().Bottom();
470 aOrg=rGF.GetUserArea().TopLeft();
471 aOrg-=rGF.GetPaperRect().TopLeft();
473 if (!rRect.IsEmpty()) {
474 Size a1PixSiz(rOut.PixelToLogic(Size(1,1)));
475 tools::Long nX1Pix=a1PixSiz.Width(); // add 1 pixel of tolerance
476 tools::Long nY1Pix=a1PixSiz.Height();
477 if (x1<rRect.Left() -nX1Pix) x1=rRect.Left() -nX1Pix;
478 if (x2>rRect.Right() +nX1Pix) x2=rRect.Right() +nX1Pix;
479 if (y1<rRect.Top() -nY1Pix) y1=rRect.Top() -nY1Pix;
480 if (y2>rRect.Bottom()+nY1Pix) y2=rRect.Bottom()+nY1Pix;
483 tools::Long xBigOrg=aOrg.X()+nWrX;
484 while (xBigOrg>=x1) xBigOrg-=nx1;
485 while (xBigOrg<x1) xBigOrg+=nx1;
486 tools::Long xFinOrg=xBigOrg;
487 while (xFinOrg>=x1) xFinOrg-=nx2;
488 while (xFinOrg<x1) xFinOrg+=nx2;
490 tools::Long yBigOrg=aOrg.Y()+nWrY;
491 while (yBigOrg>=y1) yBigOrg-=ny1;
492 while (yBigOrg<y1) yBigOrg+=ny1;
493 tools::Long yFinOrg=yBigOrg;
494 while (yFinOrg>=y1) yFinOrg-=ny2;
495 while (yFinOrg<y1) yFinOrg+=ny2;
497 if( x1 <= x2 && y1 <= y2 )
499 if( bHoriLines )
501 DrawGridFlags nGridFlags = ( bHoriSolid ? DrawGridFlags::HorzLines : DrawGridFlags::Dots );
502 sal_uInt16 nSteps = sal_uInt16(nx1 / nx2);
503 sal_uInt32 nRestPerStepMul1000 = nSteps ? ( ((nx1 * 1000)/ nSteps) - (nx2 * 1000) ) : 0;
504 sal_uInt32 nStepOffset = 0;
505 sal_uInt16 nPointOffset = 0;
507 for(sal_uInt16 a=0;a<nSteps;a++)
509 // draw
510 rOut.DrawGrid(
511 tools::Rectangle( xFinOrg + (a * nx2) + nPointOffset, yBigOrg, x2, y2 ),
512 Size( nx1, ny1 ), nGridFlags );
514 // do a step
515 nStepOffset += nRestPerStepMul1000;
516 while(nStepOffset >= 1000)
518 nStepOffset -= 1000;
519 nPointOffset++;
524 if( bVertLines )
526 DrawGridFlags nGridFlags = ( bVertSolid ? DrawGridFlags::VertLines : DrawGridFlags::Dots );
527 sal_uInt16 nSteps = sal_uInt16(ny1 / ny2);
528 sal_uInt32 nRestPerStepMul1000 = nSteps ? ( ((ny1 * 1000L)/ nSteps) - (ny2 * 1000L) ) : 0;
529 sal_uInt32 nStepOffset = 0;
530 sal_uInt16 nPointOffset = 0;
532 for(sal_uInt16 a=0;a<nSteps;a++)
534 // draw
535 rOut.DrawGrid(
536 tools::Rectangle( xBigOrg, yFinOrg + (a * ny2) + nPointOffset, x2, y2 ),
537 Size( nx1, ny1 ), nGridFlags );
539 // do a step
540 nStepOffset += nRestPerStepMul1000;
541 while(nStepOffset >= 1000)
543 nStepOffset -= 1000;
544 nPointOffset++;
551 rOut.EnableMapMode(bMap0);
552 rOut.SetLineColor(aOriginalLineColor);
555 void SdrPageView::AdjHdl()
557 GetView().AdjustMarkHdl();
560 // return true if changed, false if unchanged
561 bool SdrPageView::SetLayer(const OUString& rName, SdrLayerIDSet& rBS, bool bJa)
563 if (!GetPage())
564 return false;
566 SdrLayerID nID = GetPage()->GetLayerAdmin().GetLayerID(rName);
568 if (SDRLAYER_NOTFOUND == nID)
569 return false;
571 if (rBS.IsSet(nID) == bJa)
572 return false;
574 rBS.Set(nID, bJa);
575 return true;
578 bool SdrPageView::IsLayer(const OUString& rName, const SdrLayerIDSet& rBS) const
580 if(!GetPage())
581 return false;
583 bool bRet(false);
585 if (!rName.isEmpty())
587 SdrLayerID nId = GetPage()->GetLayerAdmin().GetLayerID(rName);
589 if(SDRLAYER_NOTFOUND != nId)
591 bRet = rBS.IsSet(nId);
595 return bRet;
598 bool SdrPageView::IsObjMarkable(SdrObject const * pObj) const
600 if (!pObj)
601 return false;
602 if (pObj->IsMarkProtect())
603 return false; // excluded from selection?
604 if (!pObj->IsVisible())
605 return false; // only visible are selectable
606 if (!pObj->IsInserted())
607 return false; // Obj deleted?
608 if (auto pObjGroup = dynamic_cast<const SdrObjGroup*>(pObj))
610 // If object is a Group object, visibility may depend on
611 // multiple layers. If one object is markable, Group is markable.
612 SdrObjList* pObjList = pObjGroup->GetSubList();
614 if (pObjList && pObjList->GetObjCount())
616 for (const rtl::Reference<SdrObject>& pCandidate : *pObjList)
618 // call recursively
619 if (IsObjMarkable(pCandidate.get()))
620 return true;
622 return false;
624 else
626 // #i43302#
627 // Allow empty groups to be selected to be able to delete them
628 return true;
631 if (!pObj->Is3DObj() && pObj->getSdrPageFromSdrObject() != GetPage())
633 // Obj suddenly in different Page
634 return false;
637 // the layer has to be visible and must not be locked
638 SdrLayerID nL = pObj->GetLayer();
639 if (!m_aLayerVisi.IsSet(nL))
640 return false;
641 if (m_aLayerLock.IsSet(nL))
642 return false;
643 return true;
646 void SdrPageView::SetPageOrigin(const Point& rOrg)
648 if (rOrg != maPageOrigin)
650 maPageOrigin = rOrg;
651 if (GetView().IsGridVisible())
653 InvalidateAllWin();
658 void SdrPageView::ImpInvalidateHelpLineArea(sal_uInt16 nNum) const
660 if (!(GetView().IsHlplVisible() && nNum<m_aHelpLines.GetCount())) return;
662 const SdrHelpLine& rHL=m_aHelpLines[nNum];
664 for(sal_uInt32 a(0); a < GetView().PaintWindowCount(); a++)
666 SdrPaintWindow* pCandidate = GetView().GetPaintWindow(a);
668 if(pCandidate->OutputToWindow())
670 OutputDevice& rOutDev = pCandidate->GetOutputDevice();
671 tools::Rectangle aR(rHL.GetBoundRect(rOutDev));
672 Size aSiz(rOutDev.PixelToLogic(Size(1,1)));
673 aR.AdjustLeft( -(aSiz.Width()) );
674 aR.AdjustRight(aSiz.Width() );
675 aR.AdjustTop( -(aSiz.Height()) );
676 aR.AdjustBottom(aSiz.Height() );
677 const_cast<SdrView&>(GetView()).InvalidateOneWin(rOutDev, aR);
682 void SdrPageView::SetHelpLines(const SdrHelpLineList& rHLL)
684 m_aHelpLines=rHLL;
685 InvalidateAllWin();
688 void SdrPageView::SetHelpLine(sal_uInt16 nNum, const SdrHelpLine& rNewHelpLine)
690 if (nNum >= m_aHelpLines.GetCount() || m_aHelpLines[nNum] == rNewHelpLine)
691 return;
693 bool bNeedRedraw = true;
694 if (m_aHelpLines[nNum].GetKind()==rNewHelpLine.GetKind()) {
695 switch (rNewHelpLine.GetKind()) {
696 case SdrHelpLineKind::Vertical : if (m_aHelpLines[nNum].GetPos().X()==rNewHelpLine.GetPos().X()) bNeedRedraw = false; break;
697 case SdrHelpLineKind::Horizontal: if (m_aHelpLines[nNum].GetPos().Y()==rNewHelpLine.GetPos().Y()) bNeedRedraw = false; break;
698 default: break;
699 } // switch
701 if (bNeedRedraw) ImpInvalidateHelpLineArea(nNum);
702 m_aHelpLines[nNum]=rNewHelpLine;
703 if (bNeedRedraw) ImpInvalidateHelpLineArea(nNum);
706 void SdrPageView::DeleteHelpLine(sal_uInt16 nNum)
708 if (nNum<m_aHelpLines.GetCount()) {
709 ImpInvalidateHelpLineArea(nNum);
710 m_aHelpLines.Delete(nNum);
714 void SdrPageView::InsertHelpLine(const SdrHelpLine& rHL)
716 sal_uInt16 nNum = m_aHelpLines.GetCount();
717 m_aHelpLines.Insert(rHL,nNum);
718 if (GetView().IsHlplVisible())
719 ImpInvalidateHelpLineArea(nNum);
722 // set current group and list
723 void SdrPageView::SetCurrentGroupAndList(SdrObject* pNewGroup, SdrObjList* pNewList)
725 if(m_pCurrentGroup != pNewGroup)
727 m_pCurrentGroup = pNewGroup;
729 if(m_pCurrentList != pNewList)
731 m_pCurrentList = pNewList;
735 bool SdrPageView::EnterGroup(SdrObject* pObj)
737 if(!pObj || !pObj->IsGroupObject())
738 return false;
740 // Don't allow enter Diagrams
741 if(nullptr != pObj && pObj->isDiagram())
742 return false;
744 const bool bGlueInvalidate(GetView().ImpIsGlueVisible());
746 if (bGlueInvalidate)
748 GetView().GlueInvalidate();
751 // deselect all
752 GetView().UnmarkAll();
754 // set current group and list
755 SdrObjList* pNewObjList = pObj->GetSubList();
756 SetCurrentGroupAndList(pObj, pNewObjList);
758 // select contained object if only one object is contained,
759 // else select nothing and let the user decide what to do next
760 if(pNewObjList && pNewObjList->GetObjCount() == 1)
762 SdrObject* pFirstObject = pNewObjList->GetObj(0);
764 if(GetView().GetSdrPageView())
766 GetView().MarkObj(pFirstObject, GetView().GetSdrPageView());
770 // build new handles
771 GetView().AdjustMarkHdl();
773 // invalidate only when view wants to visualize group entering
774 InvalidateAllWin();
776 if (bGlueInvalidate)
778 GetView().GlueInvalidate();
781 return true;
784 void SdrPageView::LeaveOneGroup()
786 SdrObject* pLastGroup = GetCurrentGroup();
787 if (!pLastGroup)
788 return;
790 bool bGlueInvalidate = GetView().ImpIsGlueVisible();
792 if(bGlueInvalidate)
793 GetView().GlueInvalidate();
795 SdrObject* pParentGroup = pLastGroup->getParentSdrObjectFromSdrObject();
796 SdrObjList* pParentList = GetPage();
798 if(pParentGroup)
799 pParentList = pParentGroup->GetSubList();
801 // deselect everything
802 GetView().UnmarkAll();
804 // allocations, pCurrentGroup and pCurrentList need to be set
805 SetCurrentGroupAndList(pParentGroup, pParentList);
807 // select the group we just left
808 if (GetView().GetSdrPageView())
809 GetView().MarkObj(pLastGroup, GetView().GetSdrPageView());
811 GetView().AdjustMarkHdl();
813 // invalidate only if view wants to visualize group entering
814 InvalidateAllWin();
816 if(bGlueInvalidate)
817 GetView().GlueInvalidate();
820 void SdrPageView::LeaveAllGroup()
822 SdrObject* pLastGroup = GetCurrentGroup();
823 if (!pLastGroup)
824 return;
826 bool bGlueInvalidate = GetView().ImpIsGlueVisible();
828 if(bGlueInvalidate)
829 GetView().GlueInvalidate();
831 // deselect everything
832 GetView().UnmarkAll();
834 // allocations, pCurrentGroup and pCurrentList always need to be set
835 SetCurrentGroupAndList(nullptr, GetPage());
837 // find and select uppermost group
838 while (pLastGroup->getParentSdrObjectFromSdrObject())
839 pLastGroup = pLastGroup->getParentSdrObjectFromSdrObject();
841 if (GetView().GetSdrPageView())
842 GetView().MarkObj(pLastGroup, GetView().GetSdrPageView());
844 GetView().AdjustMarkHdl();
846 // invalidate only when view wants to visualize group entering
847 InvalidateAllWin();
849 if(bGlueInvalidate)
850 GetView().GlueInvalidate();
853 sal_uInt16 SdrPageView::GetEnteredLevel() const
855 sal_uInt16 nCount=0;
856 SdrObject* pGrp=GetCurrentGroup();
857 while (pGrp!=nullptr) {
858 nCount++;
859 pGrp=pGrp->getParentSdrObjectFromSdrObject();
861 return nCount;
864 void SdrPageView::CheckCurrentGroup()
866 SdrObject* pGrp(GetCurrentGroup());
868 while(nullptr != pGrp &&
869 (!pGrp->IsInserted() || nullptr == pGrp->getParentSdrObjListFromSdrObject() || nullptr == pGrp->getSdrPageFromSdrObject()))
871 // anything outside of the borders?
872 pGrp = pGrp->getParentSdrObjectFromSdrObject();
875 if(pGrp != GetCurrentGroup())
877 if(nullptr != pGrp)
879 EnterGroup(pGrp);
881 else
883 LeaveAllGroup();
888 // Set background color for svx at SdrPageViews
889 void SdrPageView::SetApplicationBackgroundColor(Color aBackgroundColor)
891 maBackgroundColor = aBackgroundColor;
895 // Set document color for svx at SdrPageViews
896 void SdrPageView::SetApplicationDocumentColor(Color aDocumentColor)
898 maDocumentColor = aDocumentColor;
902 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */