1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svx.hxx" 26 27 #include "tablehandles.hxx" 28 29 #include <vcl/svapp.hxx> 30 #include <vcl/outdev.hxx> 31 #include <vcl/salbtype.hxx> 32 #include <vcl/canvastools.hxx> 33 #include <vcl/hatch.hxx> 34 #include <basegfx/polygon/b2dpolygon.hxx> 35 #include <basegfx/polygon/b2dpolypolygontools.hxx> 36 #include <basegfx/range/b2drectangle.hxx> 37 #include <basegfx/polygon/b2dpolygontools.hxx> 38 #include <svx/sdr/overlay/overlayobject.hxx> 39 #include <svx/sdr/overlay/overlaymanager.hxx> 40 #include <svx/sdrpagewindow.hxx> 41 #include <svx/sdrpaintwindow.hxx> 42 #include <svx/svdmrkv.hxx> 43 #include <svx/svdpagv.hxx> 44 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 45 #include <svx/sdr/overlay/overlayhatchrect.hxx> 46 #include <drawinglayer/primitive2d/hiddengeometryprimitive2d.hxx> 47 48 namespace sdr { namespace table { 49 50 // -------------------------------------------------------------------- 51 52 class OverlayTableEdge : public sdr::overlay::OverlayObject 53 { 54 protected: 55 basegfx::B2DPolyPolygon maPolyPolygon; 56 bool mbVisible; 57 58 // geometry creation for OverlayObject 59 virtual drawinglayer::primitive2d::Primitive2DSequence createOverlayObjectPrimitive2DSequence(); 60 61 public: 62 OverlayTableEdge( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bVisible ); 63 virtual ~OverlayTableEdge(); 64 }; 65 66 // -------------------------------------------------------------------- 67 68 TableEdgeHdl::TableEdgeHdl( const Point& rPnt, bool bHorizontal, sal_Int32 nMin, sal_Int32 nMax, sal_Int32 nEdges ) 69 : SdrHdl( rPnt, HDL_USER ) 70 , mbHorizontal( bHorizontal ) 71 , mnMin( nMin ) 72 , mnMax( nMax ) 73 , maEdges(nEdges) 74 { 75 } 76 77 void TableEdgeHdl::SetEdge( sal_Int32 nEdge, sal_Int32 nStart, sal_Int32 nEnd, TableEdgeState eState ) 78 { 79 if( (nEdge >= 0) && (nEdge <= sal::static_int_cast<sal_Int32>(maEdges.size())) ) 80 { 81 maEdges[nEdge].mnStart = nStart; 82 maEdges[nEdge].mnEnd = nEnd; 83 maEdges[nEdge].meState = eState; 84 } 85 else 86 { 87 OSL_ENSURE( false, "sdr::table::TableEdgeHdl::SetEdge(), invalid edge!" ); 88 } 89 } 90 91 Pointer TableEdgeHdl::GetPointer() const 92 { 93 if( mbHorizontal ) 94 return POINTER_VSPLIT; 95 else 96 return POINTER_HSPLIT; 97 } 98 99 sal_Int32 TableEdgeHdl::GetValidDragOffset( const SdrDragStat& rDrag ) const 100 { 101 return std::min( std::max( static_cast<sal_Int32>(mbHorizontal ? rDrag.GetDY() : rDrag.GetDX()), mnMin ), mnMax ); 102 } 103 104 basegfx::B2DPolyPolygon TableEdgeHdl::getSpecialDragPoly(const SdrDragStat& rDrag) const 105 { 106 basegfx::B2DPolyPolygon aVisible; 107 basegfx::B2DPolyPolygon aInvisible; 108 109 // create and return visible and non-visible parts for drag 110 getPolyPolygon(aVisible, aInvisible, &rDrag); 111 aVisible.append(aInvisible); 112 113 return aVisible; 114 } 115 116 void TableEdgeHdl::getPolyPolygon(basegfx::B2DPolyPolygon& rVisible, basegfx::B2DPolyPolygon& rInvisible, const SdrDragStat* pDrag) const 117 { 118 // changed method to create visible and invisible partial polygons in one run in 119 // separate PolyPolygons; both kinds are used 120 basegfx::B2DPoint aOffset(aPos.X(), aPos.Y()); 121 rVisible.clear(); 122 rInvisible.clear(); 123 124 if( pDrag ) 125 { 126 int n = mbHorizontal ? 1 : 0; 127 aOffset[n] = aOffset[n] + GetValidDragOffset( *pDrag ); 128 } 129 130 basegfx::B2DPoint aStart(aOffset), aEnd(aOffset); 131 int nPos = mbHorizontal ? 0 : 1; 132 TableEdgeVector::const_iterator aIter( maEdges.begin() ); 133 134 while( aIter != maEdges.end() ) 135 { 136 TableEdge aEdge(*aIter++); 137 138 aStart[nPos] = aOffset[nPos] + aEdge.mnStart; 139 aEnd[nPos] = aOffset[nPos] + aEdge.mnEnd; 140 141 basegfx::B2DPolygon aPolygon; 142 aPolygon.append( aStart ); 143 aPolygon.append( aEnd ); 144 145 if(aEdge.meState == Visible) 146 { 147 rVisible.append(aPolygon); 148 } 149 else 150 { 151 rInvisible.append(aPolygon); 152 } 153 } 154 } 155 156 void TableEdgeHdl::CreateB2dIAObject() 157 { 158 GetRidOfIAObject(); 159 160 if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden()) 161 { 162 SdrMarkView* pView = pHdlList->GetView(); 163 SdrPageView* pPageView = pView->GetSdrPageView(); 164 165 if(pPageView) 166 { 167 basegfx::B2DPolyPolygon aVisible; 168 basegfx::B2DPolyPolygon aInvisible; 169 170 // get visible and invisible parts 171 getPolyPolygon(aVisible, aInvisible, 0); 172 173 if(aVisible.count() || aInvisible.count()) 174 { 175 for(sal_uInt32 nWindow = 0; nWindow < pPageView->PageWindowCount(); nWindow++) 176 { 177 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(nWindow); 178 179 if(rPageWindow.GetPaintWindow().OutputToWindow()) 180 { 181 if(rPageWindow.GetOverlayManager()) 182 { 183 if(aVisible.count()) 184 { 185 // create overlay object for visible parts 186 sdr::overlay::OverlayObject* pOverlayObject = new OverlayTableEdge(aVisible, true); 187 rPageWindow.GetOverlayManager()->add(*pOverlayObject); 188 maOverlayGroup.append(*pOverlayObject); 189 } 190 191 if(aInvisible.count()) 192 { 193 // also create overlay object vor invisible parts to allow 194 // a standard HitTest using the primitives from that overlay object 195 // (see OverlayTableEdge implementation) 196 sdr::overlay::OverlayObject* pOverlayObject = new OverlayTableEdge(aInvisible, false); 197 rPageWindow.GetOverlayManager()->add(*pOverlayObject); 198 maOverlayGroup.append(*pOverlayObject); 199 } 200 } 201 } 202 } 203 } 204 } 205 } 206 } 207 208 ////////////////////////////////////////////////////////////////////////////// 209 210 OverlayTableEdge::OverlayTableEdge( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bVisible ) 211 : OverlayObject(Color(COL_GRAY)) 212 , maPolyPolygon( rPolyPolygon ) 213 , mbVisible(bVisible) 214 { 215 } 216 217 OverlayTableEdge::~OverlayTableEdge() 218 { 219 } 220 221 drawinglayer::primitive2d::Primitive2DSequence OverlayTableEdge::createOverlayObjectPrimitive2DSequence() 222 { 223 drawinglayer::primitive2d::Primitive2DSequence aRetval; 224 225 if(maPolyPolygon.count()) 226 { 227 // Discussed with CL. Currently i will leave the transparence out since this 228 // a little bit expensive. We may check the look with drag polygons later 229 const drawinglayer::primitive2d::Primitive2DReference aReference( 230 new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D( 231 maPolyPolygon, 232 getBaseColor().getBColor())); 233 234 if(mbVisible) 235 { 236 // visible, just return as sequence 237 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); 238 } 239 else 240 { 241 // embed in HiddenGeometryPrimitive2D to support HitTest of this invisible 242 // overlay object 243 const drawinglayer::primitive2d::Primitive2DSequence aSequence(&aReference, 1); 244 const drawinglayer::primitive2d::Primitive2DReference aNewReference( 245 new drawinglayer::primitive2d::HiddenGeometryPrimitive2D(aSequence)); 246 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aNewReference, 1); 247 } 248 } 249 250 return aRetval; 251 } 252 253 // ==================================================================== 254 255 TableBorderHdl::TableBorderHdl( const Rectangle& rRect ) 256 : SdrHdl( rRect.TopLeft(), HDL_MOVE ) 257 , maRectangle( rRect ) 258 { 259 260 } 261 262 Pointer TableBorderHdl::GetPointer() const 263 { 264 return POINTER_MOVE; 265 } 266 267 // create marker for this kind 268 void TableBorderHdl::CreateB2dIAObject() 269 { 270 GetRidOfIAObject(); 271 272 if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden()) 273 { 274 SdrMarkView* pView = pHdlList->GetView(); 275 SdrPageView* pPageView = pView->GetSdrPageView(); 276 277 if(pPageView) 278 { 279 for(sal_uInt32 nWindow = 0; nWindow < pPageView->PageWindowCount(); nWindow++) 280 { 281 // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b]; 282 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(nWindow); 283 284 if(rPageWindow.GetPaintWindow().OutputToWindow()) 285 { 286 if(rPageWindow.GetOverlayManager()) 287 { 288 const basegfx::B2DRange aRange(vcl::unotools::b2DRectangleFromRectangle(maRectangle)); 289 sdr::overlay::OverlayObject* pOverlayObject = new sdr::overlay::OverlayHatchRect( 290 aRange.getMinimum(), 291 aRange.getMaximum(), 292 Color(0x80, 0x80, 0x80), 293 6.0, 294 0.0, 295 45 * F_PI180, 296 0.0); 297 298 rPageWindow.GetOverlayManager()->add(*pOverlayObject); 299 maOverlayGroup.append(*pOverlayObject); 300 } 301 } 302 } 303 } 304 } 305 } 306 307 ////////////////////////////////////////////////////////////////////////////// 308 309 } // end of namespace table 310 } // end of namespace sdr 311