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 #include <svx/xoutbmp.hxx> 31 #include <svx/dialogs.hrc> 32 #include <svx/svxids.hrc> 33 #include <contdlg.hrc> 34 #include <contwnd.hxx> 35 #include <svx/svdpage.hxx> 36 #include <svx/svdopath.hxx> 37 #include <svx/xfltrit.hxx> 38 #include <svx/xfillit.hxx> 39 #include <basegfx/polygon/b2dpolygon.hxx> 40 #include <basegfx/polygon/b2dpolypolygontools.hxx> 41 42 // #i75482# 43 #include "svx/sdrpaintwindow.hxx" 44 45 #define TRANSCOL Color( COL_WHITE ) 46 47 /************************************************************************* 48 |* 49 |* 50 |* 51 \************************************************************************/ 52 53 ContourWindow::ContourWindow( Window* pParent, const ResId& rResId ) : 54 GraphCtrl ( pParent, rResId ), 55 aWorkRect ( 0, 0, 0, 0 ), 56 bPipetteMode ( sal_False ), 57 bWorkplaceMode ( sal_False ), 58 bClickValid ( sal_False ) 59 { 60 SetWinStyle( WB_SDRMODE ); 61 } 62 63 64 /************************************************************************* 65 |* 66 |* 67 |* 68 \************************************************************************/ 69 70 ContourWindow::~ContourWindow() 71 { 72 } 73 74 75 /************************************************************************* 76 |* 77 |* 78 |* 79 \************************************************************************/ 80 81 void ContourWindow::SetPolyPolygon( const PolyPolygon& rPolyPoly ) 82 { 83 SdrPage* pPage = (SdrPage*) pModel->GetPage( 0 ); 84 const sal_uInt16 nPolyCount = rPolyPoly.Count(); 85 86 // zuerst alle Zeichenobjekte loeschen 87 aPolyPoly = rPolyPoly; 88 89 // #117412# 90 // To avoid to have destroyed objects which are still selected, it is necessary to deselect 91 // them first (!) 92 pView->UnmarkAllObj(); 93 94 pPage->Clear(); 95 96 for ( sal_uInt16 i = 0; i < nPolyCount; i++ ) 97 { 98 basegfx::B2DPolyPolygon aPolyPolygon; 99 aPolyPolygon.append(aPolyPoly[ i ].getB2DPolygon()); 100 SdrPathObj* pPathObj = new SdrPathObj( OBJ_PATHFILL, aPolyPolygon ); 101 102 if ( pPathObj ) 103 { 104 SfxItemSet aSet( pModel->GetItemPool() ); 105 106 aSet.Put( XFillStyleItem( XFILL_SOLID ) ); 107 aSet.Put( XFillColorItem( String(), TRANSCOL ) ); 108 aSet.Put( XFillTransparenceItem( 50 ) ); 109 110 //pPathObj->SetItemSetAndBroadcast(aSet); 111 pPathObj->SetMergedItemSetAndBroadcast(aSet); 112 113 pPage->InsertObject( pPathObj ); 114 } 115 } 116 117 if ( nPolyCount ) 118 { 119 pView->MarkAll(); 120 pView->CombineMarkedObjects( sal_False ); 121 } 122 123 pModel->SetChanged( sal_False ); 124 } 125 126 127 /************************************************************************* 128 |* 129 |* 130 |* 131 \************************************************************************/ 132 133 const PolyPolygon& ContourWindow::GetPolyPolygon() 134 { 135 if ( pModel->IsChanged() ) 136 { 137 SdrPage* pPage = (SdrPage*) pModel->GetPage( 0 ); 138 139 aPolyPoly = PolyPolygon(); 140 141 if ( pPage && pPage->GetObjCount() ) 142 { 143 SdrPathObj* pPathObj = (SdrPathObj*)pPage->GetObj(0L); 144 // Not sure if subdivision is needed for ContourWindow, but maybe it cannot handle 145 // curves at all. Keeping subdivision here for security 146 const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(pPathObj->GetPathPoly())); 147 aPolyPoly = PolyPolygon(aB2DPolyPolygon); 148 } 149 150 pModel->SetChanged( sal_False ); 151 } 152 153 return aPolyPoly; 154 } 155 156 157 /************************************************************************* 158 |* 159 |* 160 |* 161 \************************************************************************/ 162 163 void ContourWindow::InitSdrModel() 164 { 165 GraphCtrl::InitSdrModel(); 166 167 SfxItemSet aSet( pModel->GetItemPool() ); 168 169 aSet.Put( XFillColorItem( String(), TRANSCOL ) ); 170 aSet.Put( XFillTransparenceItem( 50 ) ); 171 pView->SetAttributes( aSet ); 172 pView->SetFrameDragSingles( sal_True ); 173 } 174 175 176 /************************************************************************* 177 |* 178 |* 179 |* 180 \************************************************************************/ 181 182 void ContourWindow::SdrObjCreated( const SdrObject& ) 183 { 184 pView->MarkAll(); 185 pView->CombineMarkedObjects( sal_False ); 186 } 187 188 189 /************************************************************************* 190 |* 191 |* 192 |* 193 \************************************************************************/ 194 195 sal_Bool ContourWindow::IsContourChanged() const 196 { 197 SdrPage* pPage = (SdrPage*) pModel->GetPage( 0 ); 198 sal_Bool bRet = sal_False; 199 200 if ( pPage && pPage->GetObjCount() ) 201 bRet = ( (SdrPathObj*) pPage->GetObj( 0 ) )->GetPathPoly().count() && pModel->IsChanged(); 202 203 return bRet; 204 } 205 206 207 /************************************************************************* 208 |* 209 |* 210 |* 211 \************************************************************************/ 212 213 void ContourWindow::MouseButtonDown( const MouseEvent& rMEvt ) 214 { 215 if ( bWorkplaceMode ) 216 { 217 const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) ); 218 219 SetPolyPolygon( PolyPolygon() ); 220 aWorkRect = Rectangle( aLogPt, aLogPt ); 221 Paint( Rectangle( Point(), GetGraphicSize() ) ); 222 SetEditMode( sal_True ); 223 } 224 225 if ( !bPipetteMode ) 226 GraphCtrl::MouseButtonDown( rMEvt ); 227 } 228 229 230 /************************************************************************* 231 |* 232 |* 233 |* 234 \************************************************************************/ 235 236 void ContourWindow::MouseMove( const MouseEvent& rMEvt ) 237 { 238 bClickValid = sal_False; 239 240 if ( bPipetteMode ) 241 { 242 const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) ); 243 244 aPipetteColor = GetPixel( aLogPt ); 245 Control::MouseMove( rMEvt ); 246 247 if ( aPipetteLink.IsSet() && Rectangle( Point(), GetGraphicSize() ).IsInside( aLogPt ) ) 248 { 249 SetPointer( POINTER_REFHAND ); 250 aPipetteLink.Call( this ); 251 } 252 } 253 else 254 GraphCtrl::MouseMove( rMEvt ); 255 } 256 257 258 /************************************************************************* 259 |* 260 |* 261 |* 262 \************************************************************************/ 263 264 void ContourWindow::MouseButtonUp(const MouseEvent& rMEvt) 265 { 266 Point aTmpPoint; 267 const Rectangle aGraphRect( aTmpPoint, GetGraphicSize() ); 268 const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) ); 269 270 bClickValid = aGraphRect.IsInside( aLogPt ); 271 ReleaseMouse(); 272 273 if ( bPipetteMode ) 274 { 275 Control::MouseButtonUp( rMEvt ); 276 277 if ( aPipetteClickLink.IsSet() ) 278 aPipetteClickLink.Call( this ); 279 } 280 else if ( bWorkplaceMode ) 281 { 282 GraphCtrl::MouseButtonUp( rMEvt ); 283 284 aWorkRect.Right() = aLogPt.X(); 285 aWorkRect.Bottom() = aLogPt.Y(); 286 aWorkRect.Intersection( aGraphRect ); 287 aWorkRect.Justify(); 288 289 if ( aWorkRect.Left() != aWorkRect.Right() && aWorkRect.Top() != aWorkRect.Bottom() ) 290 { 291 PolyPolygon _aPolyPoly( GetPolyPolygon() ); 292 293 _aPolyPoly.Clip( aWorkRect ); 294 SetPolyPolygon( _aPolyPoly ); 295 pView->SetWorkArea( aWorkRect ); 296 } 297 else 298 pView->SetWorkArea( aGraphRect ); 299 300 Invalidate( aGraphRect ); 301 302 if ( aWorkplaceClickLink.IsSet() ) 303 aWorkplaceClickLink.Call( this ); 304 } 305 else 306 GraphCtrl::MouseButtonUp( rMEvt ); 307 } 308 309 310 /************************************************************************* 311 |* 312 |* 313 |* 314 \************************************************************************/ 315 316 void ContourWindow::Paint( const Rectangle& rRect ) 317 { 318 // #i75482# 319 // encapsulate the redraw using Begin/End and use the returned 320 // data to get the target output device (e.g. when pre-rendering) 321 SdrPaintWindow* pPaintWindow = pView->BeginCompleteRedraw(this); 322 OutputDevice& rTarget = pPaintWindow->GetTargetOutputDevice(); 323 324 const Graphic& rGraphic = GetGraphic(); 325 const Color& rOldLineColor = GetLineColor(); 326 const Color& rOldFillColor = GetFillColor(); 327 328 rTarget.SetLineColor( Color( COL_BLACK ) ); 329 rTarget.SetFillColor( Color( COL_WHITE ) ); 330 331 rTarget.DrawRect( Rectangle( Point(), GetGraphicSize() ) ); 332 333 rTarget.SetLineColor( rOldLineColor ); 334 rTarget.SetFillColor( rOldFillColor ); 335 336 if ( rGraphic.GetType() != GRAPHIC_NONE ) 337 rGraphic.Draw( &rTarget, Point(), GetGraphicSize() ); 338 339 if ( aWorkRect.Left() != aWorkRect.Right() && aWorkRect.Top() != aWorkRect.Bottom() ) 340 { 341 PolyPolygon _aPolyPoly( 2, 2 ); 342 const Color aOldFillColor( GetFillColor() ); 343 344 _aPolyPoly.Insert( Rectangle( Point(), GetGraphicSize() ) ); 345 _aPolyPoly.Insert( aWorkRect ); 346 347 rTarget.SetFillColor( COL_LIGHTRED ); 348 rTarget.DrawTransparent( _aPolyPoly, 50 ); 349 rTarget.SetFillColor( aOldFillColor ); 350 } 351 352 // #i75482# 353 const Region aRepaintRegion(rRect); 354 pView->DoCompleteRedraw(*pPaintWindow, aRepaintRegion); 355 pView->EndCompleteRedraw(*pPaintWindow, true); 356 } 357 358 // eof 359