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