xref: /trunk/main/sc/source/ui/view/drawview.cxx (revision ebec3577f479a42baae329cb36e2e94f09279de8)
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_ATTR_PARA_ADJUST_LEFT );
229     rBindings.Invalidate( SID_ATTR_PARA_ADJUST_RIGHT );
230     rBindings.Invalidate( SID_ATTR_PARA_ADJUST_BLOCK );
231     rBindings.Invalidate( SID_ATTR_PARA_ADJUST_CENTER);
232     rBindings.Invalidate( SID_ALIGNLEFT );
233     rBindings.Invalidate( SID_ALIGNCENTERHOR );
234     rBindings.Invalidate( SID_ALIGNRIGHT );
235     rBindings.Invalidate( SID_ALIGNBLOCK );
236     rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_10 );
237     rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_15 );
238     rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_20 );
239     rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
240     rBindings.Invalidate( SID_SET_SUB_SCRIPT );
241     rBindings.Invalidate( SID_ATTR_CHAR_KERNING );
242     rBindings.Invalidate( SID_ATTR_CHAR_STRIKEOUT );
243     rBindings.Invalidate( SID_ATTR_CHAR_SHADOWED );
244     rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
245     rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
246     rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
247     rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
248     // pseudo slots for Format menu
249     rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
250     rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
251     rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
252     rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
253 }
254 
255 //void ScDrawView::DrawMarks( OutputDevice* pOut ) const
256 //{
257 //  DBG_ASSERT(pOut, "ScDrawView::DrawMarks: No OutputDevice (!)");
258 //  SdrPaintWindow* pPaintWindow = FindPaintWindow(*pOut);
259 //
260 //  if(pPaintWindow)
261 //  {
262 //      if(pPaintWindow->isXorVisible())
263 //      {
264 //          ToggleShownXor(pOut, 0L);
265 //      }
266 //  }
267 //}
268 
269 void ScDrawView::SetMarkedToLayer( sal_uInt8 nLayerNo )
270 {
271     if (AreObjectsMarked())
272     {
273         //  #i11702# use SdrUndoObjectLayerChange for undo
274         //  STR_UNDO_SELATTR is "Attributes" - should use a different text later
275         BegUndo( ScGlobal::GetRscString( STR_UNDO_SELATTR ) );
276 
277         const SdrMarkList& rMark = GetMarkedObjectList();
278         sal_uLong nCount = rMark.GetMarkCount();
279         for (sal_uLong i=0; i<nCount; i++)
280         {
281             SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj();
282             if ( !pObj->ISA(SdrUnoObj) && (pObj->GetLayer() != SC_LAYER_INTERN) )
283             {
284                 AddUndo( new SdrUndoObjectLayerChange( *pObj, pObj->GetLayer(), (SdrLayerID)nLayerNo) );
285                 pObj->SetLayer( nLayerNo );
286             }
287         }
288 
289         EndUndo();
290 
291         //  repaint is done in SetLayer
292 
293         pViewData->GetDocShell()->SetDrawModified();
294 
295         //  #84073# check mark list now instead of later in a timer
296         CheckMarked();
297         MarkListHasChanged();
298     }
299 }
300 
301 bool ScDrawView::HasMarkedControl() const
302 {
303     SdrObjListIter aIter( GetMarkedObjectList() );
304     for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
305         if( pObj->ISA( SdrUnoObj ) )
306             return true;
307     return false;
308 }
309 
310 bool ScDrawView::HasMarkedInternal() const
311 {
312     // internal objects should not be inside a group, but who knows...
313     SdrObjListIter aIter( GetMarkedObjectList() );
314     for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
315         if( pObj->GetLayer() == SC_LAYER_INTERN )
316             return true;
317     return false;
318 }
319 
320 void ScDrawView::UpdateWorkArea()
321 {
322     SdrPage* pPage = GetModel()->GetPage(static_cast<sal_uInt16>(nTab));
323     if (pPage)
324     {
325         Point aPos;
326         Size aPageSize( pPage->GetSize() );
327         Rectangle aNewArea( aPos, aPageSize );
328         if ( aPageSize.Width() < 0 )
329         {
330             //  RTL: from max.negative (left) to zero (right)
331             aNewArea.Right() = 0;
332             aNewArea.Left() = aPageSize.Width() + 1;
333         }
334         SetWorkArea( aNewArea );
335     }
336     else
337     {
338         DBG_ERROR("Page nicht gefunden");
339     }
340 }
341 
342 void ScDrawView::DoCut()
343 {
344     DoCopy();
345     BegUndo( ScGlobal::GetRscString( STR_UNDO_CUT ) );
346     DeleteMarked();     // auf dieser View - von der 505f Umstellung nicht betroffen
347     EndUndo();
348 }
349 
350 void ScDrawView::GetScale( Fraction& rFractX, Fraction& rFractY ) const
351 {
352     rFractX = aScaleX;
353     rFractY = aScaleY;
354 }
355 
356 void ScDrawView::RecalcScale()
357 {
358     double nPPTX;
359     double nPPTY;
360     Fraction aZoomX(1,1);
361     Fraction aZoomY(1,1);
362 
363     if (pViewData)
364     {
365         nTab = pViewData->GetTabNo();
366         nPPTX = pViewData->GetPPTX();
367         nPPTY = pViewData->GetPPTY();
368         aZoomX = pViewData->GetZoomX();
369         aZoomY = pViewData->GetZoomY();
370     }
371     else
372     {
373         Point aLogic = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
374         nPPTX = aLogic.X() / 1000.0;
375         nPPTY = aLogic.Y() / 1000.0;
376                                             //! Zoom uebergeben ???
377     }
378 
379     SCCOL nEndCol = 0;
380     SCROW nEndRow = 0;
381     pDoc->GetTableArea( nTab, nEndCol, nEndRow );
382     if (nEndCol<20)
383         nEndCol = 20;
384     if (nEndRow<20)
385         nEndRow = 20;   // #i116848# instead of a large row number for an empty sheet, heights are multiplied in CalcScale
386 
387     ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev,aZoomX,aZoomY,nPPTX,nPPTY,
388                             aScaleX,aScaleY );
389 }
390 
391 void ScDrawView::DoConnect(SdrOle2Obj* pOleObj)
392 {
393     if ( pViewData )
394         pViewData->GetViewShell()->ConnectObject( pOleObj );
395 }
396 
397 void ScDrawView::MarkListHasChanged()
398 {
399     FmFormView::MarkListHasChanged();
400 
401     UpdateBrowser();
402 
403     ScTabViewShell* pViewSh = pViewData->GetViewShell();
404 
405     // #i110829# remove the cell selection only if drawing objects are selected
406     if ( !bInConstruct && GetMarkedObjectList().GetMarkCount() )
407     {
408         pViewSh->Unmark();      // remove cell selection
409 
410         //  #65379# end cell edit mode if drawing objects are selected
411         SC_MOD()->InputEnterHandler();
412     }
413 
414     //  IP deaktivieren
415 
416     ScModule* pScMod = SC_MOD();
417     bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
418 
419     ScClient* pClient = (ScClient*) pViewSh->GetIPClient();
420     if ( pClient && pClient->IsObjectInPlaceActive() && !bUnoRefDialog )
421     {
422         //  #41730# beim ViewShell::Activate aus dem Reset2Open nicht die Handles anzeigen
423         //HMHbDisableHdl = sal_True;
424         pClient->DeactivateObject();
425         //HMHbDisableHdl = sal_False;
426         //  Image-Ole wieder durch Grafik ersetzen passiert jetzt in ScClient::UIActivate
427     }
428 
429     //  Ole-Objekt selektiert?
430 
431     SdrOle2Obj* pOle2Obj = NULL;
432     SdrGrafObj* pGrafObj = NULL;
433     SdrMediaObj* pMediaObj = NULL;
434 
435     const SdrMarkList& rMarkList = GetMarkedObjectList();
436     sal_uLong nMarkCount = rMarkList.GetMarkCount();
437 
438     if ( nMarkCount == 0 && !pViewData->GetViewShell()->IsDrawSelMode() && !bInConstruct )
439     {
440         //  relock layers that may have been unlocked before
441         LockBackgroundLayer();
442         LockInternalLayer();
443     }
444 
445     sal_Bool bSubShellSet = sal_False;
446     if (nMarkCount == 1)
447     {
448         SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
449         if (pObj->GetObjIdentifier() == OBJ_OLE2)
450         {
451             pOle2Obj = (SdrOle2Obj*) pObj;
452             if (!pDoc->IsChart(pObj) )
453                 pViewSh->SetOleObjectShell(sal_True);
454             else
455                 pViewSh->SetChartShell(sal_True);
456             bSubShellSet = sal_True;
457         }
458         else if (pObj->GetObjIdentifier() == OBJ_GRAF)
459         {
460             pGrafObj = (SdrGrafObj*) pObj;
461             pViewSh->SetGraphicShell(sal_True);
462             bSubShellSet = sal_True;
463         }
464         else if (pObj->GetObjIdentifier() == OBJ_MEDIA)
465         {
466             pMediaObj = (SdrMediaObj*) pObj;
467             pViewSh->SetMediaShell(sal_True);
468             bSubShellSet = sal_True;
469         }
470         else if (pObj->GetObjIdentifier() != OBJ_TEXT   // Verhindern, das beim Anlegen
471                     || !pViewSh->IsDrawTextShell())     // eines TextObjekts auf die
472         {                                               // DrawShell umgeschaltet wird.
473             pViewSh->SetDrawShell(sal_True);                //@#70206#
474         }
475     }
476 
477     if ( nMarkCount && !bSubShellSet )
478     {
479         sal_Bool bOnlyControls = sal_True;
480         sal_Bool bOnlyGraf     = sal_True;
481         for (sal_uLong i=0; i<nMarkCount; i++)
482         {
483             SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
484             if ( pObj->ISA( SdrObjGroup ) )
485             {
486                 const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
487                 sal_uLong nListCount = pLst->GetObjCount();
488                 if ( nListCount == 0 )
489                 {
490                     //  #104156# An empty group (may occur during Undo) is no control or graphics object.
491                     //  Creating the form shell during undo would lead to problems with the undo manager.
492                     bOnlyControls = sal_False;
493                     bOnlyGraf = sal_False;
494                 }
495                 for ( sal_uInt16 j = 0; j < nListCount; ++j )
496                 {
497                     SdrObject *pSubObj = pLst->GetObj( j );
498 
499                     if (!pSubObj->ISA(SdrUnoObj))
500                         bOnlyControls = sal_False;
501                     if (pSubObj->GetObjIdentifier() != OBJ_GRAF)
502                         bOnlyGraf = sal_False;
503 
504                     if ( !bOnlyControls && !bOnlyGraf ) break;
505                 }
506             }
507             else
508             {
509                 if (!pObj->ISA(SdrUnoObj))
510                     bOnlyControls = sal_False;
511                 if (pObj->GetObjIdentifier() != OBJ_GRAF)
512                     bOnlyGraf = sal_False;
513             }
514 
515             if ( !bOnlyControls && !bOnlyGraf ) break;
516         }
517 
518         if(bOnlyControls)
519         {
520             pViewSh->SetDrawFormShell(sal_True);            // jetzt UNO-Controls
521         }
522         else if(bOnlyGraf)
523         {
524             pViewSh->SetGraphicShell(sal_True);
525         }
526         else if(nMarkCount>1)
527         {
528             pViewSh->SetDrawShell(sal_True);
529         }
530     }
531 
532 
533 
534     //  Verben anpassen
535 
536     SfxViewFrame* pViewFrame = pViewSh->GetViewFrame();
537     sal_Bool bOle = pViewSh->GetViewFrame()->GetFrame().IsInPlace();
538     uno::Sequence< embed::VerbDescriptor > aVerbs;
539     if ( pOle2Obj && !bOle )
540     {
541         uno::Reference < embed::XEmbeddedObject > xObj = pOle2Obj->GetObjRef();
542         DBG_ASSERT( xObj.is(), "SdrOle2Obj ohne ObjRef" );
543         if (xObj.is())
544             aVerbs = xObj->getSupportedVerbs();
545     }
546     pViewSh->SetVerbs( aVerbs );
547 
548     //  Image-Map Editor
549 
550     if ( pOle2Obj )
551         UpdateIMap( pOle2Obj );
552     else if ( pGrafObj )
553         UpdateIMap( pGrafObj );
554 
555     InvalidateAttribs();                // nach dem IMap-Editor Update
556     InvalidateDrawTextAttrs();
557 
558     for(sal_uInt32 a(0L); a < PaintWindowCount(); a++)
559     {
560         SdrPaintWindow* pPaintWindow = GetPaintWindow(a);
561         OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
562 
563         if(OUTDEV_WINDOW == rOutDev.GetOutDevType())
564         {
565             ((Window&)rOutDev).Update();
566         }
567     }
568 
569     //  uno object for view returns drawing objects as selection,
570     //  so it must notify its SelectionChangeListeners
571 
572     if (pViewFrame)
573     {
574         SfxFrame& rFrame = pViewFrame->GetFrame();
575         uno::Reference<frame::XController> xController = rFrame.GetController();
576         if (xController.is())
577         {
578             ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
579             if (pImp)
580                 pImp->SelectionChanged();
581         }
582     }
583 
584     //  update selection transfer object
585 
586     pViewSh->CheckSelectionTransfer();
587 
588 }
589 
590 sal_Bool ScDrawView::SdrBeginTextEdit(
591     SdrObject* pObj,
592     SdrPageView* pPV,
593     ::Window* pWinL,
594     sal_Bool bIsNewObj,
595     SdrOutliner* pGivenOutliner,
596     OutlinerView* pGivenOutlinerView,
597     sal_Bool bDontDeleteOutliner,
598     sal_Bool bOnlyOneView,
599     sal_Bool bGrabFocus )
600 {
601     const sal_Bool bRet = FmFormView::SdrBeginTextEdit(
602         pObj, pPV, pWinL, bIsNewObj,
603         pGivenOutliner, pGivenOutlinerView, bDontDeleteOutliner,
604         bOnlyOneView, bGrabFocus );
605 
606     ScTabViewShell* pViewSh = pViewData->GetViewShell();
607     if ( pViewSh->GetViewFrame() )
608     {
609         SfxFrame& rFrame = pViewSh->GetViewFrame()->GetFrame();
610         uno::Reference< frame::XController > xController = rFrame.GetController();
611         if (xController.is())
612         {
613             ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
614             if (pImp)
615                 pImp->SelectionChanged();
616         }
617     }
618 
619     return bRet;
620 }
621 
622 
623 SdrEndTextEditKind ScDrawView::SdrEndTextEdit( sal_Bool bDontDeleteReally )
624 {
625     const SdrEndTextEditKind eRet = FmFormView::SdrEndTextEdit( bDontDeleteReally );
626 
627     ScTabViewShell* pViewSh = pViewData->GetViewShell();
628     if ( pViewSh->GetViewFrame() )
629     {
630         SfxFrame& rFrame = pViewSh->GetViewFrame()->GetFrame();
631         uno::Reference< frame::XController > xController = rFrame.GetController();
632         if (xController.is())
633         {
634             ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
635             if (pImp)
636                 pImp->SelectionChanged();
637         }
638     }
639 
640     return eRet;
641 }
642 
643 
644 void __EXPORT ScDrawView::ModelHasChanged()
645 {
646     SdrObject* pEditObj = GetTextEditObject();
647     if ( pEditObj && !pEditObj->IsInserted() && pViewData )
648     {
649         //  #111700# SdrObjEditView::ModelHasChanged will end text edit in this case,
650         //  so make sure the EditEngine's undo manager is no longer used.
651         pViewData->GetViewShell()->SetDrawTextUndo(NULL);
652         SetCreateMode();    // don't leave FuText in a funny state
653     }
654 
655     FmFormView::ModelHasChanged();
656 }
657 
658 void __EXPORT ScDrawView::UpdateUserViewOptions()
659 {
660     if (pViewData)
661     {
662         const ScViewOptions&    rOpt = pViewData->GetOptions();
663         const ScGridOptions&    rGrid = rOpt.GetGridOptions();
664 
665         sal_Bool bBigHdl = rOpt.GetOption( VOPT_BIGHANDLES );
666 
667         SetDragStripes( rOpt.GetOption( VOPT_HELPLINES ) );
668         SetSolidMarkHdl( rOpt.GetOption( VOPT_SOLIDHANDLES ) );
669         SetMarkHdlSizePixel( bBigHdl ? SC_HANDLESIZE_BIG : SC_HANDLESIZE_SMALL );
670 
671         SetGridVisible( rGrid.GetGridVisible() );
672         SetSnapEnabled( rGrid.GetUseGridSnap() );
673         SetGridSnap( rGrid.GetUseGridSnap() );
674 
675         //  Snap from grid options is no longer used
676 //      SetSnapGrid( Size( rGrid.GetFldSnapX(), rGrid.GetFldSnapY() ) );
677 
678         Fraction aFractX( rGrid.GetFldDrawX(), rGrid.GetFldDivisionX() + 1 );
679         Fraction aFractY( rGrid.GetFldDrawY(), rGrid.GetFldDivisionY() + 1 );
680         SetSnapGridWidth( aFractX, aFractY );
681 
682         SetGridCoarse( Size( rGrid.GetFldDrawX(), rGrid.GetFldDrawY() ) );
683         SetGridFine( Size( rGrid.GetFldDrawX() / (rGrid.GetFldDivisionX() + 1),
684                            rGrid.GetFldDrawY() / (rGrid.GetFldDivisionY() + 1) ) );
685     }
686 }
687 
688 #ifdef _MSC_VER
689 #pragma optimize ( "", on )
690 #endif
691 
692 sal_Bool ScDrawView::SelectObject( const String& rName )
693 {
694     UnmarkAll();
695 
696     SCTAB nObjectTab = 0;
697     SdrObject* pFound = NULL;
698 
699     SfxObjectShell* pShell = pDoc->GetDocumentShell();
700     if (pShell)
701     {
702         SdrModel* pDrawLayer = GetModel();
703         SCTAB nTabCount = pDoc->GetTableCount();
704         for (SCTAB i=0; i<nTabCount && !pFound; i++)
705         {
706             SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i));
707             DBG_ASSERT(pPage,"Page ?");
708             if (pPage)
709             {
710                 SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
711                 SdrObject* pObject = aIter.Next();
712                 while (pObject && !pFound)
713                 {
714                     if ( ScDrawLayer::GetVisibleName( pObject ) == rName )
715                     {
716                         pFound = pObject;
717                         nObjectTab = i;
718                     }
719                     pObject = aIter.Next();
720                 }
721             }
722         }
723     }
724 
725     if ( pFound )
726     {
727         ScTabView* pView = pViewData->GetView();
728         if ( nObjectTab != nTab )                               // Tabelle umschalten
729             pView->SetTabNo( nObjectTab );
730 
731         DBG_ASSERT( nTab == nObjectTab, "Tabellen umschalten hat nicht geklappt" );
732 
733         pView->ScrollToObject( pFound );
734 
735         /*  #61585# To select an object on the background layer, the layer has to
736             be unlocked even if exclusive drawing selection mode is not active
737             (this is reversed in MarkListHasChanged when nothing is selected) */
738         if ( pFound->GetLayer() == SC_LAYER_BACK &&
739                 !pViewData->GetViewShell()->IsDrawSelMode() &&
740                 !pDoc->IsTabProtected( nTab ) &&
741                 !pViewData->GetSfxDocShell()->IsReadOnly() )
742         {
743             UnlockBackgroundLayer();
744         }
745 
746         SdrPageView* pPV = GetSdrPageView();
747         MarkObj( pFound, pPV );
748     }
749 
750     return ( pFound != NULL );
751 }
752 
753 //UNUSED2008-05  String ScDrawView::GetSelectedChartName() const
754 //UNUSED2008-05  {
755 //UNUSED2008-05      //  used for modifying a chart's data area - PersistName must always be used
756 //UNUSED2008-05      //  (as in ScDocument::FindChartData and UpdateChartArea)
757 //UNUSED2008-05
758 //UNUSED2008-05      const SdrMarkList& rMarkList = GetMarkedObjectList();
759 //UNUSED2008-05      if (rMarkList.GetMarkCount() == 1)
760 //UNUSED2008-05      {
761 //UNUSED2008-05          SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
762 //UNUSED2008-05          if (pObj->GetObjIdentifier() == OBJ_OLE2)
763 //UNUSED2008-05              if ( pDoc->IsChart(pObj) )
764 //UNUSED2008-05                  return static_cast<SdrOle2Obj*>(pObj)->GetPersistName();
765 //UNUSED2008-05      }
766 //UNUSED2008-05
767 //UNUSED2008-05      return EMPTY_STRING;        // nichts gefunden
768 //UNUSED2008-05  }
769 
770 FASTBOOL ScDrawView::InsertObjectSafe(SdrObject* pObj, SdrPageView& rPV, sal_uLong nOptions)
771 {
772     //  Markierung nicht aendern, wenn Ole-Objekt aktiv
773     //  (bei Drop aus Ole-Objekt wuerde sonst mitten im ExecuteDrag deaktiviert!)
774 
775     if (pViewData)
776     {
777         SfxInPlaceClient* pClient = pViewData->GetViewShell()->GetIPClient();
778         if ( pClient && pClient->IsObjectInPlaceActive() )
779             nOptions |= SDRINSERT_DONTMARK;
780     }
781 
782     return InsertObjectAtView( pObj, rPV, nOptions );
783 }
784 
785 SdrObject* ScDrawView::GetMarkedNoteCaption( ScDrawObjData** ppCaptData )
786 {
787     const SdrMarkList& rMarkList = GetMarkedObjectList();
788     if( pViewData && (rMarkList.GetMarkCount() == 1) )
789     {
790         SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
791         if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, pViewData->GetTabNo() ) )
792         {
793             if( ppCaptData ) *ppCaptData = pCaptData;
794             return pObj;
795         }
796     }
797     return 0;
798 }
799 
800 void ScDrawView::LockCalcLayer( SdrLayerID nLayer, bool bLock )
801 {
802     SdrLayer* pLockLayer = GetModel()->GetLayerAdmin().GetLayerPerID( nLayer );
803     if( pLockLayer && (IsLayerLocked( pLockLayer->GetName() ) != bLock) )
804         SetLayerLocked( pLockLayer->GetName(), bLock );
805 }
806 
807 void __EXPORT ScDrawView::MakeVisible( const Rectangle& rRect, Window& rWin )
808 {
809     //! rWin richtig auswerten
810     //! ggf Zoom aendern
811 
812     if ( pViewData && pViewData->GetActiveWin() == &rWin )
813         pViewData->GetView()->MakeVisible( rRect );
814 }
815 
816 void ScDrawView::DeleteMarked()
817 {
818     // try to delete a note caption object with its cell note in the Calc document
819     ScDrawObjData* pCaptData = 0;
820     if( SdrObject* pCaptObj = GetMarkedNoteCaption( &pCaptData ) )
821     {
822         (void)pCaptObj; // prevent 'unused variable' compiler warning in pro builds
823         ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
824         ScDocShell* pDocShell = pViewData ? pViewData->GetDocShell() : 0;
825         ::svl::IUndoManager* pUndoMgr = pDocShell ? pDocShell->GetUndoManager() : 0;
826         bool bUndo = pDrawLayer && pDocShell && pUndoMgr && pDoc->IsUndoEnabled();
827 
828         // remove the cell note from document, we are its owner now
829         ScPostIt* pNote = pDoc->ReleaseNote( pCaptData->maStart );
830         DBG_ASSERT( pNote, "ScDrawView::DeleteMarked - cell note missing in document" );
831         if( pNote )
832         {
833             // rescue note data for undo (with pointer to caption object)
834             ScNoteData aNoteData = pNote->GetNoteData();
835             DBG_ASSERT( aNoteData.mpCaption == pCaptObj, "ScDrawView::DeleteMarked - caption object does not match" );
836             // collect the drawing undo action created while deleting the note
837             if( bUndo )
838                 pDrawLayer->BeginCalcUndo(false);
839             // delete the note (already removed from document above)
840             delete pNote;
841             // add the undo action for the note
842             if( bUndo )
843                 pUndoMgr->AddUndoAction( new ScUndoReplaceNote( *pDocShell, pCaptData->maStart, aNoteData, false, pDrawLayer->GetCalcUndo() ) );
844             // repaint the cell to get rid of the note marker
845             if( pDocShell )
846                 pDocShell->PostPaintCell( pCaptData->maStart );
847             // done, return now to skip call of FmFormView::DeleteMarked()
848             return;
849         }
850     }
851 
852     FmFormView::DeleteMarked();
853 }
854 
855 SdrEndTextEditKind ScDrawView::ScEndTextEdit()
856 {
857     sal_Bool bIsTextEdit = IsTextEdit();
858     SdrEndTextEditKind eKind = SdrEndTextEdit();
859 
860     if ( bIsTextEdit && pViewData )
861         pViewData->GetViewShell()->SetDrawTextUndo(NULL);   // "normaler" Undo-Manager
862 
863     return eKind;
864 }
865 
866 void ScDrawView::MarkDropObj( SdrObject* pObj )
867 {
868     if ( pDropMarkObj != pObj )
869     {
870         pDropMarkObj = pObj;
871         ImplClearCalcDropMarker();
872 
873         if(pDropMarkObj)
874         {
875             pDropMarker = new SdrDropMarkerOverlay(*this, *pDropMarkObj);
876         }
877     }
878 }
879 
880 // support enhanced text edit for draw objects
881 SdrUndoManager* ScDrawView::getSdrUndoManagerForEnhancedTextEdit() const
882 {
883     return pDoc ? dynamic_cast< SdrUndoManager* >(pDoc->GetUndoManager()) : 0;
884 }
885 
886 // eof
887