Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / svx / source / svdraw / svdview.cxx
blobecfd6f4da7c0fa01109d6d31f6d07f4c18a4fe0a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <editeng/eeitem.hxx>
31 #include "svx/svdstr.hrc" // names taken from the resource
32 #include "svx/svdglob.hxx" // StringCache
33 #include <svx/svdpagv.hxx>
34 #include <svx/svdmrkv.hxx>
35 #include <svx/svdedxv.hxx>
36 #include <svx/svdobj.hxx>
37 #include <svx/svdopath.hxx> // for GetContext
38 #include <svx/svdograf.hxx> // for GetContext
39 #include <svx/svdomedia.hxx> // for GetContext
40 #include <svx/svdetc.hxx> // for SdrEngineDefaults
42 #ifdef DBG_UTIL
43 #include <svdibrow.hxx>
44 #endif
46 #include "svx/svdoutl.hxx"
47 #include "svx/svdview.hxx"
48 #include "editeng/editview.hxx" // for GetField
49 #include "editeng/flditem.hxx" // for URLField
50 #include "svx/obj3d.hxx"
51 #include "svx/svddrgmt.hxx"
52 #include "svx/svdotable.hxx"
53 #include <tools/tenccvt.hxx>
54 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
55 #include <svx/sdr/overlay/overlaymanager.hxx>
56 #include <svx/sdrpaintwindow.hxx>
57 #include <svx/sdrpagewindow.hxx>
58 #include <svx/sdrhittesthelper.hxx>
60 ////////////////////////////////////////////////////////////////////////////////////////////////////
62 SdrViewEvent::SdrViewEvent()
63 : pHdl(NULL),
64 pObj(NULL),
65 pRootObj(NULL),
66 pPV(NULL),
67 pURLField(NULL),
68 eHit(SDRHIT_NONE),
69 eEvent(SDREVENT_NONE),
70 eHdlKind(HDL_MOVE),
71 eEndCreateCmd(SDRCREATE_NEXTPOINT),
72 nMouseClicks(0),
73 nMouseMode(0),
74 nMouseCode(0),
75 nHlplIdx(0),
76 nGlueId(0),
77 bMouseDown(sal_False),
78 bMouseUp(sal_False),
79 bDoubleHdlSize(sal_False),
80 bIsAction(sal_False),
81 bIsTextEdit(sal_False),
82 bTextEditHit(sal_False),
83 bAddMark(sal_False),
84 bUnmark(sal_False),
85 bPrevNextMark(sal_False),
86 bMarkPrev(sal_False),
87 bInsPointNewObj(sal_False),
88 bDragWithCopy(sal_False),
89 bCaptureMouse(sal_False),
90 bReleaseMouse(sal_False)
94 SdrViewEvent::~SdrViewEvent()
98 ////////////////////////////////////////////////////////////////////////////////////////////////////
99 // helper class for all D&D overlays
101 void SdrDropMarkerOverlay::ImplCreateOverlays(const SdrView& rView, const basegfx::B2DPolyPolygon& rPolyPolygon)
103 for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
105 SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
106 rtl::Reference< ::sdr::overlay::OverlayManager > xTargetOverlay = pCandidate->GetOverlayManager();
108 if (xTargetOverlay.is())
110 ::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(
111 rPolyPolygon);
112 xTargetOverlay->add(*pNew);
113 maObjects.append(*pNew);
118 SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const SdrObject& rObject)
120 ImplCreateOverlays(rView, rObject.TakeXorPoly());
123 SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const Rectangle& rRectangle)
125 basegfx::B2DPolygon aB2DPolygon;
126 aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()));
127 aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));
128 aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()));
129 aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
130 aB2DPolygon.setClosed(true);
132 basegfx::B2DPolyPolygon aB2DPolyPolygon;
133 aB2DPolyPolygon.append(aB2DPolygon);
135 ImplCreateOverlays(rView, aB2DPolyPolygon);
138 SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const Point& rStart, const Point& rEnd)
140 basegfx::B2DPolygon aB2DPolygon;
141 aB2DPolygon.append(basegfx::B2DPoint(rStart.X(), rStart.Y()));
142 aB2DPolygon.append(basegfx::B2DPoint(rEnd.X(), rEnd.Y()));
143 aB2DPolygon.setClosed(true);
145 basegfx::B2DPolyPolygon aB2DPolyPolygon;
146 aB2DPolyPolygon.append(aB2DPolygon);
148 ImplCreateOverlays(rView, aB2DPolyPolygon);
151 SdrDropMarkerOverlay::~SdrDropMarkerOverlay()
153 // The OverlayObjects are cleared using the destructor of OverlayObjectList.
154 // That destructor calls clear() at the list which removes all objects from the
155 // OverlayManager and deletes them.
159 TYPEINIT1(SdrView,SdrCreateView);
161 SdrView::SdrView(SdrModel* pModel1, OutputDevice* pOut)
162 : SdrCreateView(pModel1,pOut),
163 bNoExtendedMouseDispatcher(sal_False),
164 bNoExtendedKeyDispatcher(sal_False),
165 bNoExtendedCommandDispatcher(sal_False),
166 mbMasterPagePaintCaching(sal_False)
168 bTextEditOnObjectsWithoutTextIfTextTool=sal_False;
170 maAccessibilityOptions.AddListener(this);
172 onAccessibilityOptionsChanged();
175 SdrView::~SdrView()
177 maAccessibilityOptions.RemoveListener(this);
180 sal_Bool SdrView::KeyInput(const KeyEvent& rKEvt, Window* pWin)
182 SetActualWin(pWin);
183 sal_Bool bRet=SdrCreateView::KeyInput(rKEvt,pWin);
184 if (!bRet && !IsExtendedKeyInputDispatcherEnabled()) {
185 bRet=sal_True;
186 switch (rKEvt.GetKeyCode().GetFullFunction()) {
187 case KEYFUNC_CUT : Cut(); break;
188 case KEYFUNC_COPY : Yank(); break;
189 case KEYFUNC_PASTE : Paste(pWin); break;
190 case KEYFUNC_DELETE: DeleteMarked(); break;
191 case KEYFUNC_UNDO: pMod->Undo(); break;
192 case KEYFUNC_REDO: pMod->Redo(); break;
193 case KEYFUNC_REPEAT: pMod->Repeat(*this); break;
194 default: {
195 switch (rKEvt.GetKeyCode().GetFullCode()) {
196 case KEY_ESCAPE: {
197 if (IsTextEdit()) SdrEndTextEdit();
198 if (IsAction()) BrkAction();
199 if (pWin!=NULL) pWin->ReleaseMouse();
200 } break;
201 case KEY_DELETE: DeleteMarked(); break;
202 case KEY_CUT: case KEY_DELETE+KEY_SHIFT: Cut(); break;
203 case KEY_COPY: case KEY_INSERT+KEY_MOD1: Yank(); break;
204 case KEY_PASTE: case KEY_INSERT+KEY_SHIFT: Paste(pWin); break;
205 case KEY_UNDO: case KEY_BACKSPACE+KEY_MOD2: pMod->Undo(); break;
206 case KEY_BACKSPACE+KEY_MOD2+KEY_SHIFT: pMod->Redo(); break;
207 case KEY_REPEAT: case KEY_BACKSPACE+KEY_MOD2+KEY_MOD1: pMod->Repeat(*this); break;
208 case KEY_MOD1+KEY_A: MarkAll(); break;
209 default: bRet=sal_False;
210 } // switch
212 } // switch
213 if (bRet && pWin!=NULL) {
214 pWin->SetPointer(GetPreferedPointer(
215 pWin->PixelToLogic(pWin->ScreenToOutputPixel( pWin->GetPointerPosPixel() ) ),
216 pWin,
217 rKEvt.GetKeyCode().GetModifier()));
220 return bRet;
223 sal_Bool SdrView::MouseButtonDown(const MouseEvent& rMEvt, Window* pWin)
225 SetActualWin(pWin);
226 if (rMEvt.IsLeft()) aDragStat.SetMouseDown(sal_True);
227 sal_Bool bRet=SdrCreateView::MouseButtonDown(rMEvt,pWin);
228 if (!bRet && !IsExtendedMouseEventDispatcherEnabled()) {
229 SdrViewEvent aVEvt;
230 PickAnything(rMEvt,SDRMOUSEBUTTONDOWN,aVEvt);
231 bRet=DoMouseEvent(aVEvt);
233 return bRet;
236 sal_Bool SdrView::MouseButtonUp(const MouseEvent& rMEvt, Window* pWin)
238 SetActualWin(pWin);
239 if (rMEvt.IsLeft()) aDragStat.SetMouseDown(sal_False);
240 sal_Bool bAction=IsAction();
241 sal_Bool bRet=!bAction && SdrCreateView::MouseButtonUp(rMEvt,pWin);
242 if (!bRet && !IsExtendedMouseEventDispatcherEnabled()) {
243 SdrViewEvent aVEvt;
244 PickAnything(rMEvt,SDRMOUSEBUTTONUP,aVEvt);
245 bRet=DoMouseEvent(aVEvt);
247 return bRet;
250 sal_Bool SdrView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
252 SetActualWin(pWin);
253 aDragStat.SetMouseDown(rMEvt.IsLeft());
254 sal_Bool bRet=SdrCreateView::MouseMove(rMEvt,pWin);
255 if (!IsExtendedMouseEventDispatcherEnabled() && !IsTextEditInSelectionMode()) {
256 SdrViewEvent aVEvt;
257 PickAnything(rMEvt,SDRMOUSEMOVE,aVEvt);
258 if (DoMouseEvent(aVEvt)) bRet=sal_True;
261 return bRet;
264 sal_Bool SdrView::Command(const CommandEvent& rCEvt, Window* pWin)
266 SetActualWin(pWin);
267 sal_Bool bRet=SdrCreateView::Command(rCEvt,pWin);
268 return bRet;
271 sal_Bool SdrView::GetAttributes(SfxItemSet& rTargetSet, sal_Bool bOnlyHardAttr) const
273 return SdrCreateView::GetAttributes(rTargetSet, bOnlyHardAttr);
276 SfxStyleSheet* SdrView::GetStyleSheet() const
278 return SdrCreateView::GetStyleSheet();
281 SdrHitKind SdrView::PickAnything(const MouseEvent& rMEvt, sal_uInt16 nEventKind, SdrViewEvent& rVEvt) const
283 rVEvt.bMouseDown=nEventKind==SDRMOUSEBUTTONDOWN;
284 rVEvt.bMouseUp=nEventKind==SDRMOUSEBUTTONUP;
285 rVEvt.nMouseClicks=rMEvt.GetClicks();
286 rVEvt.nMouseMode=rMEvt.GetMode();
287 rVEvt.nMouseCode=rMEvt.GetButtons() | rMEvt.GetModifier();
288 const OutputDevice* pOut=pActualOutDev;
289 if (pOut==NULL)
291 pOut = GetFirstOutputDevice();
293 Point aPnt(rMEvt.GetPosPixel());
294 if (pOut!=NULL) aPnt=pOut->PixelToLogic(aPnt);
295 rVEvt.aLogicPos=aPnt;
296 return PickAnything(aPnt,rVEvt);
299 // Dragging with the Mouse (Move)
300 // Example when creating a rectangle: MouseDown has to happen without a ModKey,
301 // else we usually force a selection (see below).
302 // When pressing Shift, Ctrl and Alt at the same time while doing a MouseMove,
303 // a centered, not snapped square is created.
304 // The dual allocation of Ortho and Shift won't usually create a problem, as the
305 // two functions are in most cases mutually exclusive. Only shearing (the kind
306 // that happens when contorting, not when rotating) can use both functions at
307 // the same time. To get around this, the user can use e. g. help lines.
308 #define MODKEY_NoSnap bCtrl /* temporarily disable snapping */
309 #define MODKEY_Ortho bShift /* ortho */
310 #define MODKEY_Center bAlt /* create/resize centeredly */
311 #define MODKEY_AngleSnap bShift
312 #define MODKEY_CopyDrag bCtrl /* drag and copy */
314 // click somewhere (MouseDown)
315 #define MODKEY_PolyPoly bAlt /* new Poly at InsPt and at Create */
316 #define MODKEY_MultiMark bShift /* MarkObj without doing UnmarkAll first */
317 #define MODKEY_Unmark bAlt /* deselect with a dragged frame */
318 #define MODKEY_ForceMark bCtrl /* force dragging a frame, even if there's an object at cursor position */
319 #define MODKEY_DeepMark bAlt /* MarkNextObj */
320 #define MODKEY_DeepBackw bShift /* MarkNextObj but backwards */
322 SdrHitKind SdrView::PickAnything(const Point& rLogicPos, SdrViewEvent& rVEvt) const
324 const OutputDevice* pOut=pActualOutDev;
325 if (pOut==NULL)
327 pOut = GetFirstOutputDevice();
330 // #i73628# Use a non-changeable copy of he logic position
331 const Point aLocalLogicPosition(rLogicPos);
333 sal_Bool bEditMode=IsEditMode();
334 sal_Bool bPointMode=bEditMode && HasMarkablePoints();
335 sal_Bool bGluePointMode=IsGluePointEditMode();
336 sal_Bool bInsPolyPt=bPointMode && IsInsObjPointMode() && IsInsObjPointPossible();
337 sal_Bool bInsGluePt=bGluePointMode && IsInsGluePointMode() && IsInsGluePointPossible();
338 sal_Bool bIsTextEdit=IsTextEdit();
339 sal_Bool bTextEditHit=IsTextEditHit(aLocalLogicPosition,0/*nHitTolLog*/);
340 sal_Bool bTextEditSel=IsTextEditInSelectionMode();
341 sal_Bool bShift=(rVEvt.nMouseCode & KEY_SHIFT) !=0;
342 sal_Bool bCtrl=(rVEvt.nMouseCode & KEY_MOD1) !=0;
343 sal_Bool bAlt=(rVEvt.nMouseCode & KEY_MOD2) !=0;
344 SdrHitKind eHit=SDRHIT_NONE;
345 SdrHdl* pHdl=pOut!=NULL && !bTextEditSel ? PickHandle(aLocalLogicPosition) : NULL;
346 SdrPageView* pPV=NULL;
347 SdrObject* pObj=NULL;
348 SdrObject* pHitObj=NULL;
349 sal_uInt16 nHitPassNum=0;
350 sal_uInt16 nHlplIdx=0;
351 sal_uInt16 nGlueId=0;
352 if (bTextEditHit || bTextEditSel)
354 eHit=SDRHIT_TEXTEDIT;
355 bTextEditHit=sal_True;
357 else if (pHdl!=NULL)
359 eHit=SDRHIT_HANDLE; // handle is hit: highest priority
361 else if (bEditMode && IsHlplVisible() && IsHlplFront() && pOut!=NULL && PickHelpLine(aLocalLogicPosition,nHitTolLog,*pOut,nHlplIdx,pPV))
363 eHit=SDRHIT_HELPLINE; // help line in the foreground hit: can be moved now
365 else if (bGluePointMode && PickGluePoint(aLocalLogicPosition,pObj,nGlueId,pPV))
367 eHit=SDRHIT_GLUEPOINT; // deselected glue point hit
369 else if (PickObj(aLocalLogicPosition,nHitTolLog,pHitObj,pPV,SDRSEARCH_DEEP|SDRSEARCH_MARKED,&pObj,NULL,&nHitPassNum))
371 eHit=SDRHIT_MARKEDOBJECT;
372 ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( pObj );
373 if( pTableObj )
375 sal_Int32 nX = 0, nY = 0;
376 switch( pTableObj->CheckTableHit( aLocalLogicPosition, nX, nY, 0 ) )
378 case sdr::table::SDRTABLEHIT_CELL:
379 eHit = SDRHIT_CELL;
380 break;
381 case sdr::table::SDRTABLEHIT_CELLTEXTAREA:
382 eHit = SDRHIT_TEXTEDITOBJ;
383 break;
384 default:
385 break;
389 else if (PickObj(aLocalLogicPosition,nHitTolLog,pHitObj,pPV,SDRSEARCH_DEEP|SDRSEARCH_ALSOONMASTER|SDRSEARCH_WHOLEPAGE,&pObj,NULL,&nHitPassNum))
391 // MasterPages and WholePage for Macro and URL
392 eHit=SDRHIT_UNMARKEDOBJECT;
393 ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( pObj );
394 if( pTableObj )
396 sal_Int32 nX = 0, nY = 0;
397 switch( pTableObj->CheckTableHit( aLocalLogicPosition, nX, nY, 0 ) )
399 case sdr::table::SDRTABLEHIT_CELL:
400 eHit = SDRHIT_CELL;
401 break;
402 case sdr::table::SDRTABLEHIT_CELLTEXTAREA:
403 eHit = SDRHIT_TEXTEDITOBJ;
404 break;
405 default:
406 break;
410 else if (bEditMode && IsHlplVisible() && !IsHlplFront() && pOut!=NULL && PickHelpLine(aLocalLogicPosition,nHitTolLog,*pOut,nHlplIdx,pPV))
412 eHit=SDRHIT_HELPLINE; // help line in foreground hit: can be moved now
414 if (IsMacroMode() && eHit==SDRHIT_UNMARKEDOBJECT)
416 bool bRoot=pObj->HasMacro();
417 sal_Bool bDeep=pObj!=pHitObj && pHitObj->HasMacro();
418 sal_Bool bMid=sal_False; // Have we hit upon a grouped group with a macro?
419 SdrObject* pMidObj=NULL;
420 if (pObj!=pHitObj)
422 SdrObject* pObjTmp=NULL;
423 pObjTmp=pHitObj->GetUpGroup();
424 if (pObjTmp==pObj) pObjTmp=NULL;
425 while (pObjTmp!=NULL)
427 if (pObjTmp->HasMacro())
429 bMid=sal_True;
430 pMidObj=pObjTmp;
432 pObjTmp=pObjTmp->GetUpGroup();
433 if (pObjTmp==pObj) pObjTmp=NULL;
437 if (bDeep || bMid || bRoot)
439 SdrObjMacroHitRec aHitRec;
440 aHitRec.aPos=aLocalLogicPosition;
441 aHitRec.aDownPos=aLocalLogicPosition;
442 aHitRec.nTol=nHitTolLog;
443 aHitRec.pVisiLayer=&pPV->GetVisibleLayers();
444 aHitRec.pPageView=pPV;
445 if (bDeep) bDeep=pHitObj->IsMacroHit(aHitRec);
446 if (bMid ) bMid =pMidObj->IsMacroHit(aHitRec);
447 if (bRoot) bRoot=pObj->IsMacroHit(aHitRec);
448 if (bRoot || bMid || bDeep)
450 // Priorities: 1. Root, 2. Mid, 3. Deep
451 rVEvt.pRootObj=pObj;
452 if (!bRoot) pObj=pMidObj;
453 if (!bRoot && !bMid) pObj=pHitObj;
454 eHit=SDRHIT_MACRO;
458 // check for URL field
459 if (IsMacroMode() && eHit==SDRHIT_UNMARKEDOBJECT)
461 SdrTextObj* pTextObj=PTR_CAST(SdrTextObj,pHitObj);
462 if (pTextObj!=NULL && pTextObj->HasText())
464 bool bTEHit(pPV &&
465 SdrObjectPrimitiveHit(*pTextObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true));
467 if (bTEHit)
469 Rectangle aTextRect;
470 Rectangle aAnchor;
471 SdrOutliner* pOutliner = &pTextObj->ImpGetDrawOutliner();
472 if( pTextObj->GetModel() )
473 pOutliner = &pTextObj->GetModel()->GetHitTestOutliner();
475 pTextObj->TakeTextRect( *pOutliner, aTextRect, sal_False, &aAnchor, sal_False );
477 // #i73628# Use a text-relative position for hit test in hit test outliner
478 Point aTemporaryTextRelativePosition(aLocalLogicPosition - aTextRect.TopLeft());
480 // account for FitToSize
481 bool bFitToSize(pTextObj->IsFitToSize());
482 if (bFitToSize) {
483 Fraction aX(aTextRect.GetWidth()-1,aAnchor.GetWidth()-1);
484 Fraction aY(aTextRect.GetHeight()-1,aAnchor.GetHeight()-1);
485 ResizePoint(aTemporaryTextRelativePosition,Point(),aX,aY);
487 // account for rotation
488 const GeoStat& rGeo=pTextObj->GetGeoStat();
489 if (rGeo.nDrehWink!=0) RotatePoint(aTemporaryTextRelativePosition,Point(),-rGeo.nSin,rGeo.nCos); // -sin for Unrotate
490 // we currently don't account for ticker text
491 if(pActualOutDev && pActualOutDev->GetOutDevType() == OUTDEV_WINDOW)
493 OutlinerView aOLV(pOutliner, (Window*)pActualOutDev);
494 const EditView& aEV=aOLV.GetEditView();
495 const SvxFieldItem* pItem=aEV.GetField(aTemporaryTextRelativePosition);
496 if (pItem!=NULL) {
497 const SvxFieldData* pFld=pItem->GetField();
498 const SvxURLField* pURL=PTR_CAST(SvxURLField,pFld);
499 if (pURL!=NULL) {
500 eHit=SDRHIT_URLFIELD;
501 rVEvt.pURLField=pURL;
509 if (nHitPassNum==SDRSEARCHPASS_DIRECT &&
510 (eHit==SDRHIT_MARKEDOBJECT || eHit==SDRHIT_UNMARKEDOBJECT) &&
511 (IsTextTool() || (IsEditMode() && IsQuickTextEditMode())) && pHitObj->HasTextEdit())
513 // Around the TextEditArea there's a border to select without going into text edit mode.
514 Rectangle aBoundRect(pHitObj->GetCurrentBoundRect());
516 // Force to SnapRect when Fontwork
517 if(pHitObj->ISA(SdrTextObj) && ((SdrTextObj*)pHitObj)->IsFontwork())
519 aBoundRect = pHitObj->GetSnapRect();
522 sal_Int32 nTolerance(nHitTolLog);
523 sal_Bool bBoundRectHit(sal_False);
525 if(pOut)
527 nTolerance = pOut->PixelToLogic(Size(2, 0)).Width();
530 if( (aLocalLogicPosition.X() >= aBoundRect.Left() - nTolerance && aLocalLogicPosition.X() <= aBoundRect.Left() + nTolerance)
531 || (aLocalLogicPosition.X() >= aBoundRect.Right() - nTolerance && aLocalLogicPosition.X() <= aBoundRect.Right() + nTolerance)
532 || (aLocalLogicPosition.Y() >= aBoundRect.Top() - nTolerance && aLocalLogicPosition.Y() <= aBoundRect.Top() + nTolerance)
533 || (aLocalLogicPosition.Y() >= aBoundRect.Bottom() - nTolerance && aLocalLogicPosition.Y() <= aBoundRect.Bottom() + nTolerance))
535 bBoundRectHit = sal_True;
538 if(!bBoundRectHit)
540 bool bTEHit(pPV &&
541 SdrObjectPrimitiveHit(*pHitObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true));
543 // TextEdit attached to an object in a locked layer
544 if (pPV->GetLockedLayers().IsSet(pHitObj->GetLayer()))
546 bTEHit=sal_False;
549 if (bTEHit)
551 rVEvt.pRootObj=pObj;
552 pObj=pHitObj;
553 eHit=SDRHIT_TEXTEDITOBJ;
557 if (nHitPassNum!=SDRSEARCHPASS_DIRECT && eHit==SDRHIT_UNMARKEDOBJECT) {
558 eHit=SDRHIT_NONE;
559 pObj=NULL;
560 pPV=NULL;
562 sal_Bool bMouseLeft=(rVEvt.nMouseCode&MOUSE_LEFT)!=0;
563 sal_Bool bMouseRight=(rVEvt.nMouseCode&MOUSE_RIGHT)!=0;
564 sal_Bool bMouseDown=rVEvt.bMouseDown;
565 sal_Bool bMouseUp=rVEvt.bMouseUp;
566 SdrEventKind eEvent=SDREVENT_NONE;
567 sal_Bool bIsAction=IsAction();
569 if (bIsAction)
571 if (bMouseDown)
573 if (bMouseRight) eEvent=SDREVENT_BCKACTION;
575 else if (bMouseUp)
577 if (bMouseLeft)
579 eEvent=SDREVENT_ENDACTION;
580 if (IsDragObj())
582 eEvent=SDREVENT_ENDDRAG;
583 rVEvt.bDragWithCopy=MODKEY_CopyDrag;
585 else if (IsCreateObj() || IsInsObjPoint())
587 eEvent=IsCreateObj() ? SDREVENT_ENDCREATE : SDREVENT_ENDINSOBJPOINT;
588 rVEvt.eEndCreateCmd=SDRCREATE_NEXTPOINT;
589 if (MODKEY_PolyPoly) rVEvt.eEndCreateCmd=SDRCREATE_NEXTOBJECT;
590 if (rVEvt.nMouseClicks>1) rVEvt.eEndCreateCmd=SDRCREATE_FORCEEND;
592 else if (IsMarking())
594 eEvent=SDREVENT_ENDMARK;
595 if (!aDragStat.IsMinMoved())
597 eEvent=SDREVENT_BRKMARK;
598 rVEvt.bAddMark=MODKEY_MultiMark;
603 else
605 eEvent=SDREVENT_MOVACTION;
608 else if (eHit==SDRHIT_TEXTEDIT)
610 eEvent=SDREVENT_TEXTEDIT;
612 else if (bMouseDown && bMouseLeft)
614 if (rVEvt.nMouseClicks==2 && rVEvt.nMouseCode==MOUSE_LEFT && pObj!=NULL && pHitObj!=NULL && pHitObj->HasTextEdit() && eHit==SDRHIT_MARKEDOBJECT)
616 rVEvt.pRootObj=pObj;
617 pObj=pHitObj;
618 eEvent=SDREVENT_BEGTEXTEDIT;
620 else if (MODKEY_ForceMark && eHit!=SDRHIT_URLFIELD)
622 eEvent=SDREVENT_BEGMARK; // AddMark,Unmark */
624 else if (eHit==SDRHIT_HELPLINE)
626 eEvent=SDREVENT_BEGDRAGHELPLINE; // nothing, actually
628 else if (eHit==SDRHIT_GLUEPOINT)
630 eEvent=SDREVENT_MARKGLUEPOINT; // AddMark+Drag
631 rVEvt.bAddMark=MODKEY_MultiMark || MODKEY_DeepMark; // if not hit with Deep
633 else if (eHit==SDRHIT_HANDLE)
635 eEvent=SDREVENT_BEGDRAGOBJ; // Mark+Drag,AddMark+Drag,DeepMark+Drag,Unmark
636 sal_Bool bGlue=pHdl->GetKind()==HDL_GLUE;
637 sal_Bool bPoly=!bGlue && IsPointMarkable(*pHdl);
638 sal_Bool bMarked=bGlue || (bPoly && pHdl->IsSelected());
639 if (bGlue || bPoly)
641 eEvent=bGlue ? SDREVENT_MARKGLUEPOINT : SDREVENT_MARKPOINT;
642 if (MODKEY_DeepMark)
644 rVEvt.bAddMark=sal_True;
645 rVEvt.bPrevNextMark=sal_True;
646 rVEvt.bMarkPrev=MODKEY_DeepBackw;
648 else if (MODKEY_MultiMark)
650 rVEvt.bAddMark=sal_True;
651 rVEvt.bUnmark=bMarked; // Toggle
652 if (bGlue)
654 pObj=pHdl->GetObj();
655 nGlueId=(sal_uInt16)pHdl->GetObjHdlNum();
658 else if (bMarked)
660 eEvent=SDREVENT_BEGDRAGOBJ; // don't change MarkState, only change Drag
664 else if (bInsPolyPt && (MODKEY_PolyPoly || (!MODKEY_MultiMark && !MODKEY_DeepMark)))
666 eEvent=SDREVENT_BEGINSOBJPOINT;
667 rVEvt.bInsPointNewObj=MODKEY_PolyPoly;
669 else if (bInsGluePt && !MODKEY_MultiMark && !MODKEY_DeepMark)
671 eEvent=SDREVENT_BEGINSGLUEPOINT;
673 else if (eHit==SDRHIT_TEXTEDITOBJ)
675 eEvent=SDREVENT_BEGTEXTEDIT; // AddMark+Drag,DeepMark+Drag,Unmark
676 if (MODKEY_MultiMark || MODKEY_DeepMark)
677 { // if not hit with Deep
678 eEvent=SDREVENT_MARKOBJ;
681 else if (eHit==SDRHIT_MACRO)
683 eEvent=SDREVENT_BEGMACROOBJ; // AddMark+Drag
684 if (MODKEY_MultiMark || MODKEY_DeepMark)
685 { // if not hit with Deep
686 eEvent=SDREVENT_MARKOBJ;
689 else if (eHit==SDRHIT_URLFIELD)
691 eEvent=SDREVENT_EXECUTEURL; // AddMark+Drag
692 if (MODKEY_MultiMark || MODKEY_DeepMark)
693 { // if not hit with Deep
694 eEvent=SDREVENT_MARKOBJ;
697 else if (eHit==SDRHIT_MARKEDOBJECT)
699 eEvent=SDREVENT_BEGDRAGOBJ; // DeepMark+Drag,Unmark
701 if (MODKEY_MultiMark || MODKEY_DeepMark)
702 { // if not hit with Deep
703 eEvent=SDREVENT_MARKOBJ;
706 else if (IsCreateMode())
708 eEvent=SDREVENT_BEGCREATEOBJ; // nothing, actually
710 else if (eHit==SDRHIT_UNMARKEDOBJECT)
712 eEvent=SDREVENT_MARKOBJ; // AddMark+Drag
714 else
716 eEvent=SDREVENT_BEGMARK;
719 if (eEvent==SDREVENT_MARKOBJ)
721 rVEvt.bAddMark=MODKEY_MultiMark || MODKEY_DeepMark; // if not hit with Deep
722 rVEvt.bPrevNextMark=MODKEY_DeepMark;
723 rVEvt.bMarkPrev=MODKEY_DeepMark && MODKEY_DeepBackw;
725 if (eEvent==SDREVENT_BEGMARK)
727 rVEvt.bAddMark=MODKEY_MultiMark;
728 rVEvt.bUnmark=MODKEY_Unmark;
731 rVEvt.bIsAction=bIsAction;
732 rVEvt.bIsTextEdit=bIsTextEdit;
733 rVEvt.bTextEditHit=bTextEditHit;
734 rVEvt.aLogicPos=aLocalLogicPosition;
735 rVEvt.pHdl=pHdl;
736 rVEvt.pObj=pObj;
737 if(rVEvt.pRootObj==NULL)
738 rVEvt.pRootObj=pObj;
739 rVEvt.pPV=pPV;
740 rVEvt.nHlplIdx=nHlplIdx;
741 rVEvt.nGlueId=nGlueId;
742 rVEvt.eHit=eHit;
743 rVEvt.eEvent=eEvent;
744 rVEvt.bCaptureMouse=bMouseLeft && bMouseDown && eEvent!=SDREVENT_NONE;
745 rVEvt.bReleaseMouse=bMouseLeft && bMouseUp;
746 #ifdef DGB_UTIL
747 if (rVEvt.pRootObj!=NULL) {
748 if (rVEvt.pRootObj->GetObjList()!=rVEvt.pPV->GetObjList()) {
749 OSL_FAIL("SdrView::PickAnything(): pRootObj->GetObjList()!=pPV->GetObjList() !");
752 #endif
753 return eHit;
756 sal_Bool SdrView::DoMouseEvent(const SdrViewEvent& rVEvt)
758 sal_Bool bRet=sal_False;
759 SdrHitKind eHit=rVEvt.eHit;
760 Point aLogicPos(rVEvt.aLogicPos);
762 sal_Bool bShift=(rVEvt.nMouseCode & KEY_SHIFT) !=0;
763 sal_Bool bCtrl=(rVEvt.nMouseCode & KEY_MOD1) !=0;
764 sal_Bool bAlt=(rVEvt.nMouseCode & KEY_MOD2) !=0;
765 sal_Bool bMouseLeft=(rVEvt.nMouseCode&MOUSE_LEFT)!=0;
766 sal_Bool bMouseDown=rVEvt.bMouseDown;
767 sal_Bool bMouseUp=rVEvt.bMouseUp;
768 if (bMouseDown) {
769 if (bMouseLeft) aDragStat.SetMouseDown(sal_True);
770 } else if (bMouseUp) {
771 if (bMouseLeft) aDragStat.SetMouseDown(sal_False);
772 } else { // else, MouseMove
773 aDragStat.SetMouseDown(bMouseLeft);
776 #ifdef MODKEY_NoSnap
777 SetSnapEnabled(!MODKEY_NoSnap);
778 #endif
779 #ifdef MODKEY_Ortho
780 SetOrtho(MODKEY_Ortho!=IsOrthoDesired());
781 #endif
782 #ifdef MODKEY_BigOrtho
783 SetBigOrtho(MODKEY_BigOrtho);
784 #endif
785 #ifdef MODKEY_AngleSnap
786 SetAngleSnapEnabled(MODKEY_AngleSnap);
787 #endif
788 #ifdef MODKEY_CopyDrag
789 SetDragWithCopy(MODKEY_CopyDrag);
790 #endif
791 #ifdef MODKEY_Center
792 SetCreate1stPointAsCenter(MODKEY_Center);
793 SetResizeAtCenter(MODKEY_Center);
794 SetCrookAtCenter(MODKEY_Center);
795 #endif
796 if (bMouseLeft && bMouseDown && rVEvt.bIsTextEdit && (eHit==SDRHIT_UNMARKEDOBJECT || eHit==SDRHIT_NONE)) {
797 SdrEndTextEdit(); // User has clicked beneath object, exit edit mode.
798 // pHdl is invalid, then, that shouldn't matter, though, as we expect
799 // pHdl==NULL (because of eHit).
801 switch (rVEvt.eEvent) {
802 case SDREVENT_NONE: bRet=sal_False; break;
803 case SDREVENT_TEXTEDIT: bRet=sal_False; break; // Events handled by the OutlinerView are not taken into account here.
804 case SDREVENT_MOVACTION: MovAction(aLogicPos); bRet=sal_True; break;
805 case SDREVENT_ENDACTION: EndAction(); bRet=sal_True; break;
806 case SDREVENT_BCKACTION: BckAction(); bRet=sal_True; break;
807 case SDREVENT_BRKACTION: BrkAction(); bRet=sal_True; break;
808 case SDREVENT_ENDMARK : EndAction(); bRet=sal_True; break;
809 case SDREVENT_BRKMARK : {
810 BrkAction();
811 if (!MarkObj(aLogicPos,nHitTolLog,rVEvt.bAddMark)) {
812 // No object hit. Do the following:
813 // 1. deselect any selected glue points
814 // 2. deselect any selected polygon points
815 // 3. deselect any selected objects
816 if (!rVEvt.bAddMark) UnmarkAll();
818 bRet=sal_True;
819 } break;
820 case SDREVENT_ENDCREATE: { // if necessary, MarkObj
821 SdrCreateCmd eCmd=SDRCREATE_NEXTPOINT;
822 if (MODKEY_PolyPoly) eCmd=SDRCREATE_NEXTOBJECT;
823 if (rVEvt.nMouseClicks>1) eCmd=SDRCREATE_FORCEEND;
824 if (!EndCreateObj(eCmd)) { // Don't evaluate event for Create? -> Select
825 if (eHit==SDRHIT_UNMARKEDOBJECT || eHit==SDRHIT_TEXTEDIT) {
826 MarkObj(rVEvt.pRootObj,rVEvt.pPV);
827 if (eHit==SDRHIT_TEXTEDIT)
829 sal_Bool bRet2(pActualOutDev && OUTDEV_WINDOW == pActualOutDev->GetOutDevType() &&
830 SdrBeginTextEdit(rVEvt.pObj, rVEvt.pPV, (Window*)pActualOutDev, sal_False, (SdrOutliner*)0L));
832 if(bRet2)
834 MouseEvent aMEvt(pActualOutDev->LogicToPixel(aLogicPos),
835 1,rVEvt.nMouseMode,rVEvt.nMouseCode,rVEvt.nMouseCode);
837 OutlinerView* pOLV=GetTextEditOutlinerView();
838 if (pOLV!=NULL) {
839 pOLV->MouseButtonDown(aMEvt); // event for the Outliner, but without double-click
840 pOLV->MouseButtonUp(aMEvt); // event for the Outliner, but without double-click
844 bRet=sal_True; // object is selected and (if necessary) TextEdit is started
845 } else bRet=sal_False; // canceled Create, nothing else
846 } else bRet=sal_True; // return sal_True for EndCreate
847 } break;
848 case SDREVENT_ENDDRAG: {
849 bRet=EndDragObj(IsDragWithCopy());
850 ForceMarkedObjToAnotherPage(); // TODO: Undo+bracing missing!
851 } break;
852 case SDREVENT_MARKOBJ: { // + (if applicable) BegDrag
853 if (!rVEvt.bAddMark) UnmarkAllObj();
854 sal_Bool bUnmark=rVEvt.bUnmark;
855 if (rVEvt.bPrevNextMark) {
856 bRet=MarkNextObj(aLogicPos,nHitTolLog,rVEvt.bMarkPrev);
857 } else {
858 SortMarkedObjects();
859 sal_uIntPtr nAnz0=GetMarkedObjectCount();
860 bRet=MarkObj(aLogicPos,nHitTolLog,rVEvt.bAddMark);
861 SortMarkedObjects();
862 sal_uIntPtr nAnz1=GetMarkedObjectCount();
863 bUnmark=nAnz1<nAnz0;
865 if (!bUnmark) {
866 BegDragObj(aLogicPos,NULL,(SdrHdl*)NULL,nMinMovLog);
867 bRet=sal_True;
869 } break;
870 case SDREVENT_MARKPOINT: { // + (if applicable) BegDrag
871 if (!rVEvt.bAddMark) UnmarkAllPoints();
872 if (rVEvt.bPrevNextMark) {
873 bRet=MarkNextPoint(aLogicPos,rVEvt.bMarkPrev);
874 } else {
875 bRet=MarkPoint(*rVEvt.pHdl,rVEvt.bUnmark);
877 if (!rVEvt.bUnmark && !rVEvt.bPrevNextMark) {
878 BegDragObj(aLogicPos,NULL,rVEvt.pHdl,nMinMovLog);
879 bRet=sal_True;
881 } break;
882 case SDREVENT_MARKGLUEPOINT: { // + (if applicable) BegDrag
883 if (!rVEvt.bAddMark) UnmarkAllGluePoints();
884 if (rVEvt.bPrevNextMark) {
885 bRet=MarkNextGluePoint(aLogicPos,rVEvt.bMarkPrev);
886 } else {
887 bRet=MarkGluePoint(rVEvt.pObj,rVEvt.nGlueId,rVEvt.pPV,rVEvt.bUnmark);
889 if (!rVEvt.bUnmark && !rVEvt.bPrevNextMark) {
890 SdrHdl* pHdl=GetGluePointHdl(rVEvt.pObj,rVEvt.nGlueId);
891 BegDragObj(aLogicPos,NULL,pHdl,nMinMovLog);
892 bRet=sal_True;
894 } break;
895 case SDREVENT_BEGMARK: bRet=BegMark(aLogicPos,rVEvt.bAddMark,rVEvt.bUnmark); break;
896 case SDREVENT_BEGINSOBJPOINT: bRet = BegInsObjPoint(aLogicPos, MODKEY_PolyPoly); break;
897 case SDREVENT_ENDINSOBJPOINT: {
898 SdrCreateCmd eCmd=SDRCREATE_NEXTPOINT;
899 if (MODKEY_PolyPoly) eCmd=SDRCREATE_NEXTOBJECT;
900 if (rVEvt.nMouseClicks>1) eCmd=SDRCREATE_FORCEEND;
901 EndInsObjPoint(eCmd);
902 bRet=sal_True;
903 } break;
904 case SDREVENT_BEGINSGLUEPOINT: bRet=BegInsGluePoint(aLogicPos); break;
905 case SDREVENT_BEGDRAGHELPLINE: bRet=BegDragHelpLine(rVEvt.nHlplIdx,rVEvt.pPV); break;
906 case SDREVENT_BEGDRAGOBJ: bRet=BegDragObj(aLogicPos,NULL,rVEvt.pHdl,nMinMovLog); break;
907 case SDREVENT_BEGCREATEOBJ: {
908 if (nAktInvent==SdrInventor && nAktIdent==OBJ_CAPTION) {
909 long nHgt=SdrEngineDefaults::GetFontHeight();
910 bRet=BegCreateCaptionObj(aLogicPos,Size(5*nHgt,2*nHgt));
911 } else bRet=BegCreateObj(aLogicPos);
912 } break;
913 case SDREVENT_BEGMACROOBJ: bRet=BegMacroObj(aLogicPos,nHitTolLog,rVEvt.pObj,rVEvt.pPV,(Window*)pActualOutDev); break;
914 case SDREVENT_BEGTEXTEDIT: {
915 if (!IsObjMarked(rVEvt.pObj)) {
916 UnmarkAllObj();
917 MarkObj(rVEvt.pRootObj,rVEvt.pPV);
920 bRet = pActualOutDev && OUTDEV_WINDOW == pActualOutDev->GetOutDevType()&&
921 SdrBeginTextEdit(rVEvt.pObj, rVEvt.pPV, (Window*)pActualOutDev, sal_False, (SdrOutliner*)0L);
923 if(bRet)
925 MouseEvent aMEvt(pActualOutDev->LogicToPixel(aLogicPos),
926 1,rVEvt.nMouseMode,rVEvt.nMouseCode,rVEvt.nMouseCode);
927 OutlinerView* pOLV=GetTextEditOutlinerView();
928 if (pOLV!=NULL) pOLV->MouseButtonDown(aMEvt); // event for the Outliner, but without double-click
930 } break;
931 default: break;
932 } // switch
933 if (bRet && pActualOutDev!=NULL && pActualOutDev->GetOutDevType()==OUTDEV_WINDOW) {
934 Window* pWin=(Window*)pActualOutDev;
935 // left mouse button pressed?
936 sal_Bool bLeftDown=(rVEvt.nMouseCode&MOUSE_LEFT)!=0 && rVEvt.bMouseDown;
937 // left mouse button released?
938 sal_Bool bLeftUp=(rVEvt.nMouseCode&MOUSE_LEFT)!=0 && rVEvt.bMouseUp;
939 // left mouse button pressed or held?
940 sal_Bool bLeftDown1=(rVEvt.nMouseCode&MOUSE_LEFT)!=0 && !rVEvt.bMouseUp;
941 pWin->SetPointer(GetPreferedPointer(rVEvt.aLogicPos,pWin,
942 rVEvt.nMouseCode & (KEY_SHIFT|KEY_MOD1|KEY_MOD2),bLeftDown1));
943 sal_Bool bAction=IsAction();
944 if (bLeftDown && bAction) pWin->CaptureMouse();
945 else if (bLeftUp || (rVEvt.bIsAction && !bAction)) pWin->ReleaseMouse();
947 return bRet;
949 #include <editeng/outlobj.hxx>
951 Pointer SdrView::GetPreferedPointer(const Point& rMousePos, const OutputDevice* pOut, sal_uInt16 nModifier, sal_Bool bLeftDown) const
953 // Actions
954 if (IsCreateObj())
956 return pAktCreate->GetCreatePointer();
958 if (mpCurrentSdrDragMethod)
960 if ((IsDraggingPoints() || IsDraggingGluePoints()) && IsMouseHideWhileDraggingPoints())
961 return Pointer(POINTER_NULL);
963 return mpCurrentSdrDragMethod->GetSdrDragPointer();
965 if (IsMarkObj() || IsMarkPoints() || IsMarkGluePoints() || IsSetPageOrg()) return Pointer(POINTER_ARROW);
966 if (IsDragHelpLine()) return GetDraggedHelpLinePointer();
967 if (IsMacroObj()) {
968 SdrObjMacroHitRec aHitRec;
969 aHitRec.aPos=pOut->LogicToPixel(rMousePos);
970 aHitRec.aDownPos=aMacroDownPos;
971 aHitRec.nTol=nMacroTol;
972 aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
973 aHitRec.pPageView=pMacroPV;
974 aHitRec.pOut=pMacroWin;
975 aHitRec.bDown=bMacroDown;
976 return pMacroObj->GetMacroPointer(aHitRec);
979 // TextEdit, ObjEdit, Macro
980 if (IsTextEdit() && (IsTextEditInSelectionMode() || IsTextEditHit(rMousePos,0/*nTol*/)))
982 if(!pOut || IsTextEditInSelectionMode())
984 if(pTextEditOutliner->IsVertical())
985 return Pointer(POINTER_TEXT_VERTICAL);
986 else
987 return Pointer(POINTER_TEXT);
989 // Outliner should return something here...
990 Point aPos(pOut->LogicToPixel(rMousePos));
991 Pointer aPointer(pTextEditOutlinerView->GetPointer(aPos));
992 if (aPointer==POINTER_ARROW)
994 if(pTextEditOutliner->IsVertical())
995 aPointer = POINTER_TEXT_VERTICAL;
996 else
997 aPointer = POINTER_TEXT;
999 return aPointer;
1002 SdrViewEvent aVEvt;
1003 aVEvt.nMouseCode=(nModifier&(KEY_SHIFT|KEY_MOD1|KEY_MOD2))|MOUSE_LEFT; // to see what would happen on MouseLeftDown
1004 aVEvt.bMouseDown=!bLeftDown; // What if ..?
1005 aVEvt.bMouseUp=bLeftDown; // What if ..?
1006 if (pOut!=NULL)
1007 ((SdrView*)this)->SetActualWin(pOut);
1008 SdrHitKind eHit=PickAnything(rMousePos,aVEvt);
1009 SdrEventKind eEvent=aVEvt.eEvent;
1010 switch (eEvent)
1012 case SDREVENT_BEGCREATEOBJ:
1013 return aAktCreatePointer;
1014 case SDREVENT_MARKOBJ:
1015 case SDREVENT_BEGMARK:
1016 return Pointer(POINTER_ARROW);
1017 case SDREVENT_MARKPOINT:
1018 case SDREVENT_MARKGLUEPOINT:
1019 return Pointer(POINTER_MOVEPOINT);
1020 case SDREVENT_BEGINSOBJPOINT:
1021 case SDREVENT_BEGINSGLUEPOINT:
1022 return Pointer(POINTER_CROSS);
1023 case SDREVENT_EXECUTEURL:
1024 return Pointer(POINTER_REFHAND);
1025 case SDREVENT_BEGMACROOBJ:
1027 SdrObjMacroHitRec aHitRec;
1028 aHitRec.aPos=aVEvt.aLogicPos;
1029 aHitRec.aDownPos=aHitRec.aPos;
1030 aHitRec.nTol=nHitTolLog;
1031 aHitRec.pVisiLayer=&aVEvt.pPV->GetVisibleLayers();
1032 aHitRec.pPageView=aVEvt.pPV;
1033 aHitRec.pOut=(OutputDevice*)pOut;
1034 return aVEvt.pObj->GetMacroPointer(aHitRec);
1036 default: break;
1037 } // switch
1039 switch(eHit)
1041 case SDRHIT_CELL:
1042 return Pointer(POINTER_ARROW);
1043 case SDRHIT_HELPLINE :
1044 return aVEvt.pPV->GetHelpLines()[aVEvt.nHlplIdx].GetPointer();
1045 case SDRHIT_GLUEPOINT:
1046 return Pointer(POINTER_MOVEPOINT);
1047 case SDRHIT_TEXTEDIT :
1048 case SDRHIT_TEXTEDITOBJ:
1050 SdrTextObj* pText = dynamic_cast< SdrTextObj* >( aVEvt.pObj );
1051 if(pText && pText->HasText())
1053 OutlinerParaObject* pParaObj = pText->GetOutlinerParaObject();
1054 if(pParaObj && pParaObj->IsVertical())
1055 return Pointer(POINTER_TEXT_VERTICAL);
1057 return Pointer(POINTER_TEXT);
1059 default: break;
1062 sal_Bool bMarkHit=eHit==SDRHIT_MARKEDOBJECT;
1063 SdrHdl* pHdl=aVEvt.pHdl;
1064 // now check the pointers for dragging
1065 if (pHdl!=NULL || bMarkHit) {
1066 SdrHdlKind eHdl= pHdl!=NULL ? pHdl->GetKind() : HDL_MOVE;
1067 sal_Bool bCorner=pHdl!=NULL && pHdl->IsCornerHdl();
1068 sal_Bool bVertex=pHdl!=NULL && pHdl->IsVertexHdl();
1069 sal_Bool bMov=eHdl==HDL_MOVE;
1070 if (bMov && (eDragMode==SDRDRAG_MOVE || eDragMode==SDRDRAG_RESIZE || bMarkedHitMovesAlways)) {
1071 if (!IsMoveAllowed()) return Pointer(POINTER_ARROW); // because double click or drag & drop is possible
1072 return Pointer(POINTER_MOVE);
1074 switch (eDragMode) {
1075 case SDRDRAG_ROTATE: {
1076 if ((bCorner || bMov) && !IsRotateAllowed(sal_True))
1077 return Pointer(POINTER_NOTALLOWED);
1079 // are 3D objects selected?
1080 sal_Bool b3DObjSelected = sal_False;
1081 for (sal_uInt32 a=0; !b3DObjSelected && a<GetMarkedObjectCount(); a++) {
1082 SdrObject* pObj = GetMarkedObjectByIndex(a);
1083 if(pObj && pObj->ISA(E3dObject))
1084 b3DObjSelected = sal_True;
1086 // If we have a 3D object, go on despite !IsShearAllowed,
1087 // because then we have a rotation instead of a shear.
1088 if (bVertex && !IsShearAllowed() && !b3DObjSelected)
1089 return Pointer(POINTER_NOTALLOWED);
1090 if (bMov)
1091 return Pointer(POINTER_ROTATE);
1092 } break;
1093 case SDRDRAG_SHEAR: case SDRDRAG_DISTORT: {
1094 if (bCorner) {
1095 if (!IsDistortAllowed(sal_True) && !IsDistortAllowed(sal_False)) return Pointer(POINTER_NOTALLOWED);
1096 else return Pointer(POINTER_REFHAND);
1098 if (bVertex && !IsShearAllowed()) return Pointer(POINTER_NOTALLOWED);
1099 if (bMov) {
1100 if (!IsMoveAllowed()) return Pointer(POINTER_ARROW); // because double click or drag & drop is possible
1101 return Pointer(POINTER_MOVE);
1103 } break;
1104 case SDRDRAG_MIRROR: {
1105 if (bCorner || bVertex || bMov) {
1106 SdrHdl* pH1=aHdl.GetHdl(HDL_REF1);
1107 SdrHdl* pH2=aHdl.GetHdl(HDL_REF2);
1108 sal_Bool b90=sal_False;
1109 sal_Bool b45=sal_False;
1110 Point aDif;
1111 if (pH1!=NULL && pH2!=NULL) {
1112 aDif=pH2->GetPos()-pH1->GetPos();
1113 b90=(aDif.X()==0) || aDif.Y()==0;
1114 b45=b90 || (Abs(aDif.X())==Abs(aDif.Y()));
1116 sal_Bool bNo=sal_False;
1117 if (!IsMirrorAllowed(sal_True,sal_True)) bNo=sal_True; // any mirroring is forbidden
1118 if (!IsMirrorAllowed(sal_False,sal_False) && !b45) bNo=sal_True; // mirroring freely is forbidden
1119 if (!IsMirrorAllowed(sal_True,sal_False) && !b90) bNo=sal_True; // mirroring horizontally/vertically is allowed
1120 if (bNo) return Pointer(POINTER_NOTALLOWED);
1121 if (b90) {
1122 return Pointer(POINTER_MIRROR);
1124 return Pointer(POINTER_MIRROR);
1126 } break;
1128 case SDRDRAG_TRANSPARENCE:
1130 if(!IsTransparenceAllowed())
1131 return Pointer(POINTER_NOTALLOWED);
1133 return Pointer(POINTER_REFHAND);
1136 case SDRDRAG_GRADIENT:
1138 if(!IsGradientAllowed())
1139 return Pointer(POINTER_NOTALLOWED);
1141 return Pointer(POINTER_REFHAND);
1144 case SDRDRAG_CROOK: {
1145 if (bCorner || bVertex || bMov) {
1146 if (!IsCrookAllowed(sal_True) && !IsCrookAllowed(sal_False)) return Pointer(POINTER_NOTALLOWED);
1147 return Pointer(POINTER_CROOK);
1151 case SDRDRAG_CROP:
1153 return Pointer(POINTER_CROP);
1156 default: {
1157 if ((bCorner || bVertex) && !IsResizeAllowed(sal_True)) return Pointer(POINTER_NOTALLOWED);
1160 if (pHdl!=NULL) return pHdl->GetPointer();
1161 if (bMov) {
1162 if (!IsMoveAllowed()) return Pointer(POINTER_ARROW); // because double click or drag & drop is possible
1163 return Pointer(POINTER_MOVE);
1166 if (eEditMode==SDREDITMODE_CREATE) return aAktCreatePointer;
1167 return Pointer(POINTER_ARROW);
1170 #define STR_NOTHING "nothing"
1171 XubString SdrView::GetStatusText()
1173 XubString aStr;
1174 XubString aName;
1176 aStr.AppendAscii(STR_NOTHING);
1178 if (pAktCreate!=NULL)
1180 aStr=pAktCreate->getSpecialDragComment(aDragStat);
1182 if(!aStr.Len())
1184 pAktCreate->TakeObjNameSingul(aName);
1185 aStr = ImpGetResStr(STR_ViewCreateObj);
1188 else if (mpCurrentSdrDragMethod)
1190 if (bInsPolyPoint || IsInsertGluePoint())
1192 aStr=aInsPointUndoStr;
1194 else
1196 if (aDragStat.IsMinMoved())
1198 OSL_TRACE("SdrView::GetStatusText(%lx) %lx", this, mpCurrentSdrDragMethod);
1199 mpCurrentSdrDragMethod->TakeSdrDragComment(aStr);
1203 else if(IsMarkObj())
1205 if(AreObjectsMarked())
1207 aStr = ImpGetResStr(STR_ViewMarkMoreObjs);
1209 else
1211 aStr = ImpGetResStr(STR_ViewMarkObjs);
1214 else if(IsMarkPoints())
1216 if(HasMarkedPoints())
1218 aStr = ImpGetResStr(STR_ViewMarkMorePoints);
1220 else
1222 aStr = ImpGetResStr(STR_ViewMarkPoints);
1224 } else if (IsMarkGluePoints())
1226 if(HasMarkedGluePoints())
1228 aStr = ImpGetResStr(STR_ViewMarkMoreGluePoints);
1230 else
1232 aStr = ImpGetResStr(STR_ViewMarkGluePoints);
1235 else if (IsTextEdit() && pTextEditOutlinerView!=NULL) {
1236 aStr=ImpGetResStr(STR_ViewTextEdit); // "TextEdit - Row y, Column x";
1237 ESelection aSel(pTextEditOutlinerView->GetSelection());
1238 long nPar=aSel.nEndPara,nLin=0,nCol=aSel.nEndPos;
1239 if (aSel.nEndPara>0) {
1240 for (sal_uInt16 nParaNum=0; nParaNum<aSel.nEndPara; nParaNum++) {
1241 nLin+=pTextEditOutliner->GetLineCount(nParaNum);
1244 // A little imperfection:
1245 // At the end of a line of any multi-line paragraph, we display the
1246 // position of the next line of the same paragraph, if there is one.
1247 sal_uInt16 nParaLine=0;
1248 sal_uIntPtr nParaLineAnz=pTextEditOutliner->GetLineCount(aSel.nEndPara);
1249 sal_Bool bBrk=sal_False;
1250 while (!bBrk) {
1251 sal_uInt16 nLen=pTextEditOutliner->GetLineLen(aSel.nEndPara,nParaLine);
1252 sal_Bool bLastLine=(nParaLine==nParaLineAnz-1);
1253 if (nCol>nLen || (!bLastLine && nCol==nLen)) {
1254 nCol-=nLen;
1255 nLin++;
1256 nParaLine++;
1257 } else bBrk=sal_True;
1258 if (nLen==0) bBrk=sal_True; // to be sure
1261 aStr.SearchAndReplaceAscii("%1", UniString::CreateFromInt32(nPar + 1));
1262 aStr.SearchAndReplaceAscii("%2", UniString::CreateFromInt32(nLin + 1));
1263 aStr.SearchAndReplaceAscii("%3", UniString::CreateFromInt32(nCol + 1));
1265 #ifdef DBG_UTIL
1266 aStr += UniString( RTL_CONSTASCII_USTRINGPARAM( ", Level " ) );
1267 aStr += UniString::CreateFromInt32( pTextEditOutliner->GetDepth( aSel.nEndPara ) );
1268 #endif
1271 if(aStr.EqualsAscii(STR_NOTHING))
1273 if (AreObjectsMarked()) {
1274 ImpTakeDescriptionStr(STR_ViewMarked,aStr);
1275 if (IsGluePointEditMode()) {
1276 if (HasMarkedGluePoints()) {
1277 ImpTakeDescriptionStr(STR_ViewMarked,aStr,0,IMPSDR_GLUEPOINTSDESCRIPTION);
1279 } else {
1280 if (HasMarkedPoints()) {
1281 ImpTakeDescriptionStr(STR_ViewMarked,aStr,0,IMPSDR_POINTSDESCRIPTION);
1284 } else {
1285 aStr.Erase();
1288 else if(aName.Len())
1290 aStr.SearchAndReplaceAscii("%1", aName);
1293 if(aStr.Len())
1295 // capitalize first letter
1296 String aTmpStr(aStr.Copy(0, 1));
1297 aTmpStr.ToUpperAscii();
1298 aStr.Replace(0, 1, aTmpStr);
1300 return aStr;
1303 SdrViewContext SdrView::GetContext() const
1305 if( IsGluePointEditMode() )
1306 return SDRCONTEXT_GLUEPOINTEDIT;
1308 const sal_uIntPtr nMarkAnz = GetMarkedObjectCount();
1310 if( HasMarkablePoints() && !IsFrameHandles() )
1312 sal_Bool bPath=sal_True;
1313 for( sal_uIntPtr nMarkNum = 0; nMarkNum < nMarkAnz && bPath; nMarkNum++ )
1314 if (!GetMarkedObjectByIndex(nMarkNum)->ISA(SdrPathObj))
1315 bPath=sal_False;
1317 if( bPath )
1318 return SDRCONTEXT_POINTEDIT;
1321 if( GetMarkedObjectCount() )
1323 sal_Bool bGraf = sal_True, bMedia = sal_True, bTable = sal_True;
1325 for( sal_uIntPtr nMarkNum = 0; nMarkNum < nMarkAnz && ( bGraf || bMedia ); nMarkNum++ )
1327 const SdrObject* pMarkObj = GetMarkedObjectByIndex( nMarkNum );
1328 DBG_ASSERT( pMarkObj, "SdrView::GetContext(), null pointer in mark list!" );
1330 if( !pMarkObj )
1331 continue;
1333 if( !pMarkObj->ISA( SdrGrafObj ) )
1334 bGraf = sal_False;
1336 if( !pMarkObj->ISA( SdrMediaObj ) )
1337 bMedia = sal_False;
1339 if( !pMarkObj->ISA( ::sdr::table::SdrTableObj ) )
1340 bTable = sal_False;
1343 if( bGraf )
1344 return SDRCONTEXT_GRAPHIC;
1345 else if( bMedia )
1346 return SDRCONTEXT_MEDIA;
1347 else if( bTable )
1348 return SDRCONTEXT_TABLE;
1351 return SDRCONTEXT_STANDARD;
1354 void SdrView::MarkAll()
1356 if (IsTextEdit()) {
1357 GetTextEditOutlinerView()->SetSelection(ESelection(0,0,0xFFFF,0xFFFF));
1358 #ifdef DBG_UTIL
1359 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1360 #endif
1361 } else if (IsGluePointEditMode()) MarkAllGluePoints();
1362 else if (HasMarkablePoints()) MarkAllPoints();
1363 else MarkAllObj();
1366 void SdrView::UnmarkAll()
1368 if (IsTextEdit()) {
1369 ESelection eSel=GetTextEditOutlinerView()->GetSelection();
1370 eSel.nStartPara=eSel.nEndPara;
1371 eSel.nStartPos=eSel.nEndPos;
1372 GetTextEditOutlinerView()->SetSelection(eSel);
1373 #ifdef DBG_UTIL
1374 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1375 #endif
1376 } else if (HasMarkedGluePoints()) UnmarkAllGluePoints();
1377 else if (HasMarkedPoints()) UnmarkAllPoints(); // Marked, not Markable!
1378 else UnmarkAllObj();
1381 const Rectangle& SdrView::GetMarkedRect() const
1383 if (IsGluePointEditMode() && HasMarkedGluePoints()) {
1384 return GetMarkedGluePointsRect();
1386 if (HasMarkedPoints()) {
1387 return GetMarkedPointsRect();
1389 return GetMarkedObjRect();
1392 void SdrView::DeleteMarked()
1394 if (IsTextEdit())
1396 SdrObjEditView::KeyInput(KeyEvent(0,KeyCode(KEYFUNC_DELETE)),pTextEditWin);
1398 else
1400 if( mxSelectionController.is() && mxSelectionController->DeleteMarked() )
1402 // action already performed by current selection controller, do nothing
1404 else if (IsGluePointEditMode() && HasMarkedGluePoints())
1406 DeleteMarkedGluePoints();
1408 else if (GetContext()==SDRCONTEXT_POINTEDIT && HasMarkedPoints())
1410 DeleteMarkedPoints();
1412 else
1414 DeleteMarkedObj();
1419 sal_Bool SdrView::BegMark(const Point& rPnt, sal_Bool bAddMark, sal_Bool bUnmark)
1421 if (bUnmark) bAddMark=sal_True;
1422 if (IsGluePointEditMode()) {
1423 if (!bAddMark) UnmarkAllGluePoints();
1424 return BegMarkGluePoints(rPnt,bUnmark);
1425 } else if (HasMarkablePoints()) {
1426 if (!bAddMark) UnmarkAllPoints();
1427 return BegMarkPoints(rPnt,bUnmark);
1428 } else {
1429 if (!bAddMark) UnmarkAllObj();
1430 return BegMarkObj(rPnt,bUnmark);
1434 void SdrView::ConfigurationChanged( ::utl::ConfigurationBroadcaster*p, sal_uInt32 nHint)
1436 onAccessibilityOptionsChanged();
1437 SdrCreateView::ConfigurationChanged(p, nHint);
1440 SvtAccessibilityOptions& SdrView::getAccessibilityOptions()
1442 return maAccessibilityOptions;
1445 /** method is called whenever the global SvtAccessibilityOptions is changed */
1446 void SdrView::onAccessibilityOptionsChanged()
1450 void SdrView::SetMasterPagePaintCaching(sal_Bool bOn)
1452 if(mbMasterPagePaintCaching != bOn)
1454 mbMasterPagePaintCaching = bOn;
1456 // reset at all SdrPageWindows
1457 SdrPageView* pPageView = GetSdrPageView();
1459 if(pPageView)
1461 for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1463 SdrPageWindow* pPageWindow = pPageView->GetPageWindow(b);
1464 DBG_ASSERT(pPageWindow, "SdrView::SetMasterPagePaintCaching: Corrupt SdrPageWindow list (!)");
1466 // force deletion of ObjectContact, so at re-display all VOCs
1467 // will be re-created with updated flag setting
1468 pPageWindow->ResetObjectContact();
1471 // force redraw of this view
1472 pPageView->InvalidateAllWin();
1478 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */