xref: /AOO41X/main/sc/source/ui/view/drawview.cxx (revision 7b6b9ddb4b63a97ea0214b9472b5270bbf674949)
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_sc.hxx"
26 
27 // INCLUDE ---------------------------------------------------------------
28 
29 #include <com/sun/star/embed/EmbedStates.hpp>
30 
31 #include <svx/svditer.hxx>
32 #include <svx/svdograf.hxx>
33 #include <svx/svdomedia.hxx>
34 #include <svx/svdogrp.hxx>
35 #include <svx/svdoole2.hxx>
36 #include <svx/svdouno.hxx>
37 #include <svx/svdpage.hxx>
38 #include <svx/svdundo.hxx>
39 #include <svx/svdocapt.hxx>
40 #include <editeng/outlobj.hxx>
41 #include <editeng/writingmodeitem.hxx>
42 #include <svx/sdrpaintwindow.hxx>
43 #include <sfx2/bindings.hxx>
44 #include <sfx2/viewfrm.hxx>
45 #include <svx/sdrundomanager.hxx>
46 
47 #include "drawview.hxx"
48 #include "global.hxx"
49 #include "viewdata.hxx"
50 #include "document.hxx"
51 #include "drawutil.hxx"
52 #include "futext.hxx"
53 #include "globstr.hrc"
54 #include "tabvwsh.hxx"
55 #include "client.hxx"
56 #include "scmod.hxx"
57 #include "drwlayer.hxx"
58 #include "docsh.hxx"
59 #include "viewuno.hxx"
60 #include "userdat.hxx"
61 #include "postit.hxx"
62 #include "undocell.hxx"
63 #include "document.hxx"
64 
65 #include "sc.hrc"
66 
67 using namespace com::sun::star;
68 
69 // -----------------------------------------------------------------------
70 
71 #define SC_HANDLESIZE_BIG       9
72 #define SC_HANDLESIZE_SMALL     7
73 
74 // -----------------------------------------------------------------------
75 
76 #ifdef _MSC_VER
77 #pragma optimize ( "", off )
78 #endif
79 
80 
81 void ScDrawView::Construct()
82 {
83     EnableExtendedKeyInputDispatcher(sal_False);
84     EnableExtendedMouseEventDispatcher(sal_False);
85     EnableExtendedCommandEventDispatcher(sal_False);
86 
87     SetFrameDragSingles(sal_True);
88 //  SetSolidMarkHdl(sal_True);              // einstellbar -> UpdateUserViewOptions
89 
90     SetMinMoveDistancePixel( 2 );
91     SetHitTolerancePixel( 2 );
92 
93     if (pViewData)
94     {
95         SCTAB nViewTab = pViewData->GetTabNo();
96         ShowSdrPage(GetModel()->GetPage(nViewTab));
97 
98         sal_Bool bEx = pViewData->GetViewShell()->IsDrawSelMode();
99         sal_Bool bProt = pDoc->IsTabProtected( nViewTab ) ||
100                      pViewData->GetSfxDocShell()->IsReadOnly();
101 
102         SdrLayer* pLayer;
103         SdrLayerAdmin& rAdmin = GetModel()->GetLayerAdmin();
104         pLayer = rAdmin.GetLayerPerID(SC_LAYER_BACK);
105         if (pLayer)
106             SetLayerLocked( pLayer->GetName(), bProt || !bEx );
107         pLayer = rAdmin.GetLayerPerID(SC_LAYER_INTERN);
108         if (pLayer)
109             SetLayerLocked( pLayer->GetName(), sal_True );
110         pLayer = rAdmin.GetLayerPerID(SC_LAYER_FRONT);
111         if (pLayer)
112         {
113             SetLayerLocked( pLayer->GetName(), bProt );
114             SetActiveLayer( pLayer->GetName() );        // FRONT als aktiven Layer setzen
115         }
116         pLayer = rAdmin.GetLayerPerID(SC_LAYER_CONTROLS);
117         if (pLayer)
118             SetLayerLocked( pLayer->GetName(), bProt );
119         pLayer = rAdmin.GetLayerPerID(SC_LAYER_HIDDEN);
120         if (pLayer)
121         {
122             SetLayerLocked( pLayer->GetName(), bProt );
123             SetLayerVisible( pLayer->GetName(), sal_False);
124         }
125 
126         SetSwapAsynchron(sal_True);
127     }
128     else
129     {
130         ShowSdrPage(GetModel()->GetPage(nTab));
131     }
132 
133     UpdateUserViewOptions();
134     RecalcScale();
135     UpdateWorkArea();
136 
137     bInConstruct = sal_False;
138 }
139 
140 void ScDrawView::ImplClearCalcDropMarker()
141 {
142     if(pDropMarker)
143     {
144         delete pDropMarker;
145         pDropMarker = 0L;
146     }
147 }
148 
149 __EXPORT ScDrawView::~ScDrawView()
150 {
151     ImplClearCalcDropMarker();
152 }
153 
154 void ScDrawView::AddCustomHdl()
155 {
156     sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
157 
158     const SdrMarkList &rMrkList = GetMarkedObjectList();
159     sal_uInt32 nCount = rMrkList.GetMarkCount();
160     for(sal_uInt32 nPos=0; nPos<nCount; nPos++ )
161     {
162         const SdrObject* pObj = rMrkList.GetMark(nPos)->GetMarkedSdrObj();
163         if(ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
164         {
165             const sal_Int32 nDelta = 1;
166 
167             Rectangle aBoundRect = pObj->GetCurrentBoundRect();
168             Point aPos;
169             if (bNegativePage)
170             {
171                 aPos = aBoundRect.TopRight();
172                 aPos.X() = -aPos.X();           // so the loop below is the same
173             }
174             else
175                 aPos = aBoundRect.TopLeft();
176             long nPosX = (long) (aPos.X() / HMM_PER_TWIPS) + nDelta;
177             long nPosY = (long) (aPos.Y() / HMM_PER_TWIPS) + nDelta;
178 
179             SCCOL nCol;
180             sal_Int32 nWidth = 0;
181 
182             for(nCol=0; nCol<=MAXCOL && nWidth<=nPosX; nCol++)
183                 nWidth += pDoc->GetColWidth(nCol,nTab);
184 
185             if(nCol > 0)
186                 --nCol;
187 
188             SCROW nRow = nPosY <= 0 ? 0 : pDoc->GetRowForHeight( nTab,
189                     (sal_uLong) nPosY);
190             if(nRow > 0)
191                 --nRow;
192 
193             ScTabView* pView = pViewData->GetView();
194             ScAddress aScAddress(nCol, nRow, nTab);
195             pView->CreateAnchorHandles(aHdl, aScAddress);
196         }
197     }
198 }
199 
200 void ScDrawView::InvalidateAttribs()
201 {
202     if (!pViewData) return;
203     SfxBindings& rBindings = pViewData->GetBindings();
204 
205         // echte Statuswerte:
206     rBindings.InvalidateAll( sal_True );
207 }
208 
209 void ScDrawView::InvalidateDrawTextAttrs()
210 {
211     if (!pViewData) return;
212     SfxBindings& rBindings = pViewData->GetBindings();
213 
214     //  cjk/ctl font items have no configured slots,
215     //  need no invalidate
216 
217     rBindings.Invalidate( SID_ATTR_CHAR_FONT );
218     rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
219     rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
220     rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
221     rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
222     rBindings.Invalidate( SID_ULINE_VAL_NONE );
223     rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
224     rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
225     rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
226     rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
227     rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
228     rBindings.Invalidate( SID_ALIGNLEFT );
229     rBindings.Invalidate( SID_ALIGNCENTERHOR );
230     rBindings.Invalidate( SID_ALIGNRIGHT );
231     rBindings.Invalidate( SID_ALIGNBLOCK );
232     rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_10 );
233     rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_15 );
234     rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_20 );
235     rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
236     rBindings.Invalidate( SID_SET_SUB_SCRIPT );
237     rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
238     rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
239     rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
240     rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
241     // pseudo slots for Format menu
242     rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
243     rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
244     rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
245     rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
246 }
247 
248 //void ScDrawView::DrawMarks( OutputDevice* pOut ) const
249 //{
250 //  DBG_ASSERT(pOut, "ScDrawView::DrawMarks: No OutputDevice (!)");
251 //  SdrPaintWindow* pPaintWindow = FindPaintWindow(*pOut);
252 //
253 //  if(pPaintWindow)
254 //  {
255 //      if(pPaintWindow->isXorVisible())
256 //      {
257 //          ToggleShownXor(pOut, 0L);
258 //      }
259 //  }
260 //}
261 
262 void ScDrawView::SetMarkedToLayer( sal_uInt8 nLayerNo )
263 {
264     if (AreObjectsMarked())
265     {
266         //  #i11702# use SdrUndoObjectLayerChange for undo
267         //  STR_UNDO_SELATTR is "Attributes" - should use a different text later
268         BegUndo( ScGlobal::GetRscString( STR_UNDO_SELATTR ) );
269 
270         const SdrMarkList& rMark = GetMarkedObjectList();
271         sal_uLong nCount = rMark.GetMarkCount();
272         for (sal_uLong i=0; i<nCount; i++)
273         {
274             SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj();
275             if ( !pObj->ISA(SdrUnoObj) && (pObj->GetLayer() != SC_LAYER_INTERN) )
276             {
277                 AddUndo( new SdrUndoObjectLayerChange( *pObj, pObj->GetLayer(), (SdrLayerID)nLayerNo) );
278                 pObj->SetLayer( nLayerNo );
279             }
280         }
281 
282         EndUndo();
283 
284         //  repaint is done in SetLayer
285 
286         pViewData->GetDocShell()->SetDrawModified();
287 
288         //  #84073# check mark list now instead of later in a timer
289         CheckMarked();
290         MarkListHasChanged();
291     }
292 }
293 
294 bool ScDrawView::HasMarkedControl() const
295 {
296     SdrObjListIter aIter( GetMarkedObjectList() );
297     for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
298         if( pObj->ISA( SdrUnoObj ) )
299             return true;
300     return false;
301 }
302 
303 bool ScDrawView::HasMarkedInternal() const
304 {
305     // internal objects should not be inside a group, but who knows...
306     SdrObjListIter aIter( GetMarkedObjectList() );
307     for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
308         if( pObj->GetLayer() == SC_LAYER_INTERN )
309             return true;
310     return false;
311 }
312 
313 void ScDrawView::UpdateWorkArea()
314 {
315     SdrPage* pPage = GetModel()->GetPage(static_cast<sal_uInt16>(nTab));
316     if (pPage)
317     {
318         Point aPos;
319         Size aPageSize( pPage->GetSize() );
320         Rectangle aNewArea( aPos, aPageSize );
321         if ( aPageSize.Width() < 0 )
322         {
323             //  RTL: from max.negative (left) to zero (right)
324             aNewArea.Right() = 0;
325             aNewArea.Left() = aPageSize.Width() + 1;
326         }
327         SetWorkArea( aNewArea );
328     }
329     else
330     {
331         DBG_ERROR("Page nicht gefunden");
332     }
333 }
334 
335 void ScDrawView::DoCut()
336 {
337     DoCopy();
338     BegUndo( ScGlobal::GetRscString( STR_UNDO_CUT ) );
339     DeleteMarked();     // auf dieser View - von der 505f Umstellung nicht betroffen
340     EndUndo();
341 }
342 
343 void ScDrawView::GetScale( Fraction& rFractX, Fraction& rFractY ) const
344 {
345     rFractX = aScaleX;
346     rFractY = aScaleY;
347 }
348 
349 void ScDrawView::RecalcScale()
350 {
351     double nPPTX;
352     double nPPTY;
353     Fraction aZoomX(1,1);
354     Fraction aZoomY(1,1);
355 
356     if (pViewData)
357     {
358         nTab = pViewData->GetTabNo();
359         nPPTX = pViewData->GetPPTX();
360         nPPTY = pViewData->GetPPTY();
361         aZoomX = pViewData->GetZoomX();
362         aZoomY = pViewData->GetZoomY();
363     }
364     else
365     {
366         Point aLogic = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
367         nPPTX = aLogic.X() / 1000.0;
368         nPPTY = aLogic.Y() / 1000.0;
369                                             //! Zoom uebergeben ???
370     }
371 
372     SCCOL nEndCol = 0;
373     SCROW nEndRow = 0;
374     pDoc->GetTableArea( nTab, nEndCol, nEndRow );
375     if (nEndCol<20)
376         nEndCol = 20;
377     if (nEndRow<20)
378         nEndRow = 20;   // #i116848# instead of a large row number for an empty sheet, heights are multiplied in CalcScale
379 
380     ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev,aZoomX,aZoomY,nPPTX,nPPTY,
381                             aScaleX,aScaleY );
382 }
383 
384 void ScDrawView::DoConnect(SdrOle2Obj* pOleObj)
385 {
386     if ( pViewData )
387         pViewData->GetViewShell()->ConnectObject( pOleObj );
388 }
389 
390 void ScDrawView::MarkListHasChanged()
391 {
392     FmFormView::MarkListHasChanged();
393 
394     UpdateBrowser();
395 
396     ScTabViewShell* pViewSh = pViewData->GetViewShell();
397 
398     // #i110829# remove the cell selection only if drawing objects are selected
399     if ( !bInConstruct && GetMarkedObjectList().GetMarkCount() )
400     {
401         pViewSh->Unmark();      // remove cell selection
402 
403         //  #65379# end cell edit mode if drawing objects are selected
404         SC_MOD()->InputEnterHandler();
405     }
406 
407     //  IP deaktivieren
408 
409     ScModule* pScMod = SC_MOD();
410     bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
411 
412     ScClient* pClient = (ScClient*) pViewSh->GetIPClient();
413     if ( pClient && pClient->IsObjectInPlaceActive() && !bUnoRefDialog )
414     {
415         //  #41730# beim ViewShell::Activate aus dem Reset2Open nicht die Handles anzeigen
416         //HMHbDisableHdl = sal_True;
417         pClient->DeactivateObject();
418         //HMHbDisableHdl = sal_False;
419         //  Image-Ole wieder durch Grafik ersetzen passiert jetzt in ScClient::UIActivate
420     }
421 
422     //  Ole-Objekt selektiert?
423 
424     SdrOle2Obj* pOle2Obj = NULL;
425     SdrGrafObj* pGrafObj = NULL;
426     SdrMediaObj* pMediaObj = NULL;
427 
428     const SdrMarkList& rMarkList = GetMarkedObjectList();
429     sal_uLong nMarkCount = rMarkList.GetMarkCount();
430 
431     if ( nMarkCount == 0 && !pViewData->GetViewShell()->IsDrawSelMode() && !bInConstruct )
432     {
433         //  relock layers that may have been unlocked before
434         LockBackgroundLayer();
435         LockInternalLayer();
436     }
437 
438     sal_Bool bSubShellSet = sal_False;
439     if (nMarkCount == 1)
440     {
441         SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
442         if (pObj->GetObjIdentifier() == OBJ_OLE2)
443         {
444             pOle2Obj = (SdrOle2Obj*) pObj;
445             if (!pDoc->IsChart(pObj) )
446                 pViewSh->SetOleObjectShell(sal_True);
447             else
448                 pViewSh->SetChartShell(sal_True);
449             bSubShellSet = sal_True;
450         }
451         else if (pObj->GetObjIdentifier() == OBJ_GRAF)
452         {
453             pGrafObj = (SdrGrafObj*) pObj;
454             pViewSh->SetGraphicShell(sal_True);
455             bSubShellSet = sal_True;
456         }
457         else if (pObj->GetObjIdentifier() == OBJ_MEDIA)
458         {
459             pMediaObj = (SdrMediaObj*) pObj;
460             pViewSh->SetMediaShell(sal_True);
461             bSubShellSet = sal_True;
462         }
463         else if (pObj->GetObjIdentifier() != OBJ_TEXT   // Verhindern, das beim Anlegen
464                     || !pViewSh->IsDrawTextShell())     // eines TextObjekts auf die
465         {                                               // DrawShell umgeschaltet wird.
466             pViewSh->SetDrawShell(sal_True);                //@#70206#
467         }
468     }
469 
470     if ( nMarkCount && !bSubShellSet )
471     {
472         sal_Bool bOnlyControls = sal_True;
473         sal_Bool bOnlyGraf     = sal_True;
474         for (sal_uLong i=0; i<nMarkCount; i++)
475         {
476             SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
477             if ( pObj->ISA( SdrObjGroup ) )
478             {
479                 const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
480                 sal_uLong nListCount = pLst->GetObjCount();
481                 if ( nListCount == 0 )
482                 {
483                     //  #104156# An empty group (may occur during Undo) is no control or graphics object.
484                     //  Creating the form shell during undo would lead to problems with the undo manager.
485                     bOnlyControls = sal_False;
486                     bOnlyGraf = sal_False;
487                 }
488                 for ( sal_uInt16 j = 0; j < nListCount; ++j )
489                 {
490                     SdrObject *pSubObj = pLst->GetObj( j );
491 
492                     if (!pSubObj->ISA(SdrUnoObj))
493                         bOnlyControls = sal_False;
494                     if (pSubObj->GetObjIdentifier() != OBJ_GRAF)
495                         bOnlyGraf = sal_False;
496 
497                     if ( !bOnlyControls && !bOnlyGraf ) break;
498                 }
499             }
500             else
501             {
502                 if (!pObj->ISA(SdrUnoObj))
503                     bOnlyControls = sal_False;
504                 if (pObj->GetObjIdentifier() != OBJ_GRAF)
505                     bOnlyGraf = sal_False;
506             }
507 
508             if ( !bOnlyControls && !bOnlyGraf ) break;
509         }
510 
511         if(bOnlyControls)
512         {
513             pViewSh->SetDrawFormShell(sal_True);            // jetzt UNO-Controls
514         }
515         else if(bOnlyGraf)
516         {
517             pViewSh->SetGraphicShell(sal_True);
518         }
519         else if(nMarkCount>1)
520         {
521             pViewSh->SetDrawShell(sal_True);
522         }
523     }
524 
525 
526 
527     //  Verben anpassen
528 
529     SfxViewFrame* pViewFrame = pViewSh->GetViewFrame();
530     sal_Bool bOle = pViewSh->GetViewFrame()->GetFrame().IsInPlace();
531     uno::Sequence< embed::VerbDescriptor > aVerbs;
532     if ( pOle2Obj && !bOle )
533     {
534         uno::Reference < embed::XEmbeddedObject > xObj = pOle2Obj->GetObjRef();
535         DBG_ASSERT( xObj.is(), "SdrOle2Obj ohne ObjRef" );
536         if (xObj.is())
537             aVerbs = xObj->getSupportedVerbs();
538     }
539     pViewSh->SetVerbs( aVerbs );
540 
541     //  Image-Map Editor
542 
543     if ( pOle2Obj )
544         UpdateIMap( pOle2Obj );
545     else if ( pGrafObj )
546         UpdateIMap( pGrafObj );
547 
548     InvalidateAttribs();                // nach dem IMap-Editor Update
549     InvalidateDrawTextAttrs();
550 
551     for(sal_uInt32 a(0L); a < PaintWindowCount(); a++)
552     {
553         SdrPaintWindow* pPaintWindow = GetPaintWindow(a);
554         OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
555 
556         if(OUTDEV_WINDOW == rOutDev.GetOutDevType())
557         {
558             ((Window&)rOutDev).Update();
559         }
560     }
561 
562     //  uno object for view returns drawing objects as selection,
563     //  so it must notify its SelectionChangeListeners
564 
565     if (pViewFrame)
566     {
567         SfxFrame& rFrame = pViewFrame->GetFrame();
568         uno::Reference<frame::XController> xController = rFrame.GetController();
569         if (xController.is())
570         {
571             ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
572             if (pImp)
573                 pImp->SelectionChanged();
574         }
575     }
576 
577     //  update selection transfer object
578 
579     pViewSh->CheckSelectionTransfer();
580 
581 }
582 
583 void __EXPORT ScDrawView::ModelHasChanged()
584 {
585     SdrObject* pEditObj = GetTextEditObject();
586     if ( pEditObj && !pEditObj->IsInserted() && pViewData )
587     {
588         //  #111700# SdrObjEditView::ModelHasChanged will end text edit in this case,
589         //  so make sure the EditEngine's undo manager is no longer used.
590         pViewData->GetViewShell()->SetDrawTextUndo(NULL);
591         SetCreateMode();    // don't leave FuText in a funny state
592     }
593 
594     FmFormView::ModelHasChanged();
595 }
596 
597 void __EXPORT ScDrawView::UpdateUserViewOptions()
598 {
599     if (pViewData)
600     {
601         const ScViewOptions&    rOpt = pViewData->GetOptions();
602         const ScGridOptions&    rGrid = rOpt.GetGridOptions();
603 
604         sal_Bool bBigHdl = rOpt.GetOption( VOPT_BIGHANDLES );
605 
606         SetDragStripes( rOpt.GetOption( VOPT_HELPLINES ) );
607         SetSolidMarkHdl( rOpt.GetOption( VOPT_SOLIDHANDLES ) );
608         SetMarkHdlSizePixel( bBigHdl ? SC_HANDLESIZE_BIG : SC_HANDLESIZE_SMALL );
609 
610         SetGridVisible( rGrid.GetGridVisible() );
611         SetSnapEnabled( rGrid.GetUseGridSnap() );
612         SetGridSnap( rGrid.GetUseGridSnap() );
613 
614         //  Snap from grid options is no longer used
615 //      SetSnapGrid( Size( rGrid.GetFldSnapX(), rGrid.GetFldSnapY() ) );
616 
617         Fraction aFractX( rGrid.GetFldDrawX(), rGrid.GetFldDivisionX() + 1 );
618         Fraction aFractY( rGrid.GetFldDrawY(), rGrid.GetFldDivisionY() + 1 );
619         SetSnapGridWidth( aFractX, aFractY );
620 
621         SetGridCoarse( Size( rGrid.GetFldDrawX(), rGrid.GetFldDrawY() ) );
622         SetGridFine( Size( rGrid.GetFldDrawX() / (rGrid.GetFldDivisionX() + 1),
623                            rGrid.GetFldDrawY() / (rGrid.GetFldDivisionY() + 1) ) );
624     }
625 }
626 
627 #ifdef _MSC_VER
628 #pragma optimize ( "", on )
629 #endif
630 
631 sal_Bool ScDrawView::SelectObject( const String& rName )
632 {
633     UnmarkAll();
634 
635     SCTAB nObjectTab = 0;
636     SdrObject* pFound = NULL;
637 
638     SfxObjectShell* pShell = pDoc->GetDocumentShell();
639     if (pShell)
640     {
641         SdrModel* pDrawLayer = GetModel();
642         SCTAB nTabCount = pDoc->GetTableCount();
643         for (SCTAB i=0; i<nTabCount && !pFound; i++)
644         {
645             SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i));
646             DBG_ASSERT(pPage,"Page ?");
647             if (pPage)
648             {
649                 SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
650                 SdrObject* pObject = aIter.Next();
651                 while (pObject && !pFound)
652                 {
653                     if ( ScDrawLayer::GetVisibleName( pObject ) == rName )
654                     {
655                         pFound = pObject;
656                         nObjectTab = i;
657                     }
658                     pObject = aIter.Next();
659                 }
660             }
661         }
662     }
663 
664     if ( pFound )
665     {
666         ScTabView* pView = pViewData->GetView();
667         if ( nObjectTab != nTab )                               // Tabelle umschalten
668             pView->SetTabNo( nObjectTab );
669 
670         DBG_ASSERT( nTab == nObjectTab, "Tabellen umschalten hat nicht geklappt" );
671 
672         pView->ScrollToObject( pFound );
673 
674         /*  #61585# To select an object on the background layer, the layer has to
675             be unlocked even if exclusive drawing selection mode is not active
676             (this is reversed in MarkListHasChanged when nothing is selected) */
677         if ( pFound->GetLayer() == SC_LAYER_BACK &&
678                 !pViewData->GetViewShell()->IsDrawSelMode() &&
679                 !pDoc->IsTabProtected( nTab ) &&
680                 !pViewData->GetSfxDocShell()->IsReadOnly() )
681         {
682             UnlockBackgroundLayer();
683         }
684 
685         SdrPageView* pPV = GetSdrPageView();
686         MarkObj( pFound, pPV );
687     }
688 
689     return ( pFound != NULL );
690 }
691 
692 //UNUSED2008-05  String ScDrawView::GetSelectedChartName() const
693 //UNUSED2008-05  {
694 //UNUSED2008-05      //  used for modifying a chart's data area - PersistName must always be used
695 //UNUSED2008-05      //  (as in ScDocument::FindChartData and UpdateChartArea)
696 //UNUSED2008-05
697 //UNUSED2008-05      const SdrMarkList& rMarkList = GetMarkedObjectList();
698 //UNUSED2008-05      if (rMarkList.GetMarkCount() == 1)
699 //UNUSED2008-05      {
700 //UNUSED2008-05          SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
701 //UNUSED2008-05          if (pObj->GetObjIdentifier() == OBJ_OLE2)
702 //UNUSED2008-05              if ( pDoc->IsChart(pObj) )
703 //UNUSED2008-05                  return static_cast<SdrOle2Obj*>(pObj)->GetPersistName();
704 //UNUSED2008-05      }
705 //UNUSED2008-05
706 //UNUSED2008-05      return EMPTY_STRING;        // nichts gefunden
707 //UNUSED2008-05  }
708 
709 FASTBOOL ScDrawView::InsertObjectSafe(SdrObject* pObj, SdrPageView& rPV, sal_uLong nOptions)
710 {
711     //  Markierung nicht aendern, wenn Ole-Objekt aktiv
712     //  (bei Drop aus Ole-Objekt wuerde sonst mitten im ExecuteDrag deaktiviert!)
713 
714     if (pViewData)
715     {
716         SfxInPlaceClient* pClient = pViewData->GetViewShell()->GetIPClient();
717         if ( pClient && pClient->IsObjectInPlaceActive() )
718             nOptions |= SDRINSERT_DONTMARK;
719     }
720 
721     return InsertObjectAtView( pObj, rPV, nOptions );
722 }
723 
724 SdrObject* ScDrawView::GetMarkedNoteCaption( ScDrawObjData** ppCaptData )
725 {
726     const SdrMarkList& rMarkList = GetMarkedObjectList();
727     if( pViewData && (rMarkList.GetMarkCount() == 1) )
728     {
729         SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
730         if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, pViewData->GetTabNo() ) )
731         {
732             if( ppCaptData ) *ppCaptData = pCaptData;
733             return pObj;
734         }
735     }
736     return 0;
737 }
738 
739 void ScDrawView::LockCalcLayer( SdrLayerID nLayer, bool bLock )
740 {
741     SdrLayer* pLockLayer = GetModel()->GetLayerAdmin().GetLayerPerID( nLayer );
742     if( pLockLayer && (IsLayerLocked( pLockLayer->GetName() ) != bLock) )
743         SetLayerLocked( pLockLayer->GetName(), bLock );
744 }
745 
746 void __EXPORT ScDrawView::MakeVisible( const Rectangle& rRect, Window& rWin )
747 {
748     //! rWin richtig auswerten
749     //! ggf Zoom aendern
750 
751     if ( pViewData && pViewData->GetActiveWin() == &rWin )
752         pViewData->GetView()->MakeVisible( rRect );
753 }
754 
755 void ScDrawView::DeleteMarked()
756 {
757     // try to delete a note caption object with its cell note in the Calc document
758     ScDrawObjData* pCaptData = 0;
759     if( SdrObject* pCaptObj = GetMarkedNoteCaption( &pCaptData ) )
760     {
761         (void)pCaptObj; // prevent 'unused variable' compiler warning in pro builds
762         ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
763         ScDocShell* pDocShell = pViewData ? pViewData->GetDocShell() : 0;
764         ::svl::IUndoManager* pUndoMgr = pDocShell ? pDocShell->GetUndoManager() : 0;
765         bool bUndo = pDrawLayer && pDocShell && pUndoMgr && pDoc->IsUndoEnabled();
766 
767         // remove the cell note from document, we are its owner now
768         ScPostIt* pNote = pDoc->ReleaseNote( pCaptData->maStart );
769         DBG_ASSERT( pNote, "ScDrawView::DeleteMarked - cell note missing in document" );
770         if( pNote )
771         {
772             // rescue note data for undo (with pointer to caption object)
773             ScNoteData aNoteData = pNote->GetNoteData();
774             DBG_ASSERT( aNoteData.mpCaption == pCaptObj, "ScDrawView::DeleteMarked - caption object does not match" );
775             // collect the drawing undo action created while deleting the note
776             if( bUndo )
777                 pDrawLayer->BeginCalcUndo();
778             // delete the note (already removed from document above)
779             delete pNote;
780             // add the undo action for the note
781             if( bUndo )
782                 pUndoMgr->AddUndoAction( new ScUndoReplaceNote( *pDocShell, pCaptData->maStart, aNoteData, false, pDrawLayer->GetCalcUndo() ) );
783             // repaint the cell to get rid of the note marker
784             if( pDocShell )
785                 pDocShell->PostPaintCell( pCaptData->maStart );
786             // done, return now to skip call of FmFormView::DeleteMarked()
787             return;
788         }
789     }
790 
791     FmFormView::DeleteMarked();
792 }
793 
794 SdrEndTextEditKind ScDrawView::ScEndTextEdit()
795 {
796     sal_Bool bIsTextEdit = IsTextEdit();
797     SdrEndTextEditKind eKind = SdrEndTextEdit();
798 
799     if ( bIsTextEdit && pViewData )
800         pViewData->GetViewShell()->SetDrawTextUndo(NULL);   // "normaler" Undo-Manager
801 
802     return eKind;
803 }
804 
805 void ScDrawView::MarkDropObj( SdrObject* pObj )
806 {
807     if ( pDropMarkObj != pObj )
808     {
809         pDropMarkObj = pObj;
810         ImplClearCalcDropMarker();
811 
812         if(pDropMarkObj)
813         {
814             pDropMarker = new SdrDropMarkerOverlay(*this, *pDropMarkObj);
815         }
816     }
817 }
818 
819 // support enhanced text edit for draw objects
820 SdrUndoManager* ScDrawView::getSdrUndoManagerForEnhancedTextEdit() const
821 {
822     return pDoc ? dynamic_cast< SdrUndoManager* >(pDoc->GetUndoManager()) : 0;
823 }
824 
825 // eof
826