xref: /AOO41X/main/svx/source/svdraw/svdedxv.cxx (revision 5443dcac4da55ae8863c5c80e8907938642a7f1b)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_svx.hxx"
24 
25 #include <com/sun/star/i18n/WordType.hpp>
26 #include <svtools/accessibilityoptions.hxx>
27 #include <svx/svdedxv.hxx>
28 #include <svl/solar.hrc>
29 #include <svl/itemiter.hxx>
30 #include <vcl/msgbox.hxx>
31 #include <vcl/hatch.hxx>
32 #include <svl/whiter.hxx>
33 #include <svl/style.hxx>
34 #include <editeng/editstat.hxx>
35 #include <tools/config.hxx>
36 #include <vcl/cursor.hxx>
37 #include <editeng/unotext.hxx>
38 #include <editeng/editeng.hxx>
39 #include <editeng/editobj.hxx>
40 #include <editeng/outlobj.hxx>
41 #include <editeng/scripttypeitem.hxx>
42 #include "svx/svditext.hxx"
43 #include <svx/svdoutl.hxx>
44 #include <svx/sdtfchim.hxx>
45 #include <svx/svdotext.hxx>
46 #include <svx/svdundo.hxx>
47 #include "svx/svditer.hxx"
48 #include "svx/svdpagv.hxx"
49 #include "svx/svdpage.hxx"
50 #include "svx/svdetc.hxx"
51 #include "svx/svdotable.hxx"
52 #include <svx/selectioncontroller.hxx>
53 #ifdef DBG_UTIL
54 #include <svdibrow.hxx>
55 #endif
56 #include <svx/svdoutl.hxx>
57 #include <svx/svddrgv.hxx>
58 #include "svx/svdstr.hrc"
59 #include "svx/svdglob.hxx"
60 #include "svx/globl3d.hxx"
61 #include <editeng/outliner.hxx>
62 #include <editeng/adjitem.hxx>
63 #include <svtools/colorcfg.hxx>
64 #include <vcl/svapp.hxx>
65 #include <svx/sdrpaintwindow.hxx>
66 #include <svx/sdrundomanager.hxx>
67 #include <svx/sdr/overlay/overlaytools.hxx>
68 #include <drawinglayer/processor2d/processor2dtools.hxx>
69 
70 ////////////////////////////////////////////////////////////////////////////////////////////////////
71 
72 void SdrObjEditView::ImpClearVars()
73 {
74     bQuickTextEditMode=sal_True;
75     bMacroMode=sal_True;
76     pTextEditOutliner=NULL;
77     pTextEditOutlinerView=NULL;
78     pTextEditPV=NULL;
79     pTextEditWin=NULL;
80     pTextEditCursorMerker=NULL;
81     pEditPara=NULL;
82     bTextEditNewObj=sal_False;
83     bMacroDown=sal_False;
84     pMacroObj=NULL;
85     pMacroPV=NULL;
86     pMacroWin=NULL;
87     nMacroTol=0;
88     bTextEditDontDelete=sal_False;
89     bTextEditOnlyOneView=sal_False;
90 }
91 
92 SdrObjEditView::SdrObjEditView(SdrModel* pModel1, OutputDevice* pOut):
93     SdrGlueEditView(pModel1,pOut),
94     mpOldTextEditUndoManager(0)
95 {
96     ImpClearVars();
97 }
98 
99 SdrObjEditView::~SdrObjEditView()
100 {
101     pTextEditWin = NULL;            // Damit es in SdrEndTextEdit kein ShowCursor gibt
102     if (IsTextEdit()) SdrEndTextEdit();
103     if (pTextEditOutliner!=NULL) {
104         delete pTextEditOutliner;
105     }
106 
107     if(mpOldTextEditUndoManager)
108     {
109         delete mpOldTextEditUndoManager;
110     }
111 }
112 
113 ////////////////////////////////////////////////////////////////////////////////////////////////////
114 
115 sal_Bool SdrObjEditView::IsAction() const
116 {
117     return IsMacroObj() || SdrGlueEditView::IsAction();
118 }
119 
120 void SdrObjEditView::MovAction(const Point& rPnt)
121 {
122     if (IsMacroObj()) MovMacroObj(rPnt);
123     SdrGlueEditView::MovAction(rPnt);
124 }
125 
126 void SdrObjEditView::EndAction()
127 {
128     if (IsMacroObj()) EndMacroObj();
129     SdrGlueEditView::EndAction();
130 }
131 
132 void SdrObjEditView::BckAction()
133 {
134     BrkMacroObj();
135     SdrGlueEditView::BckAction();
136 }
137 
138 void SdrObjEditView::BrkAction()
139 {
140     BrkMacroObj();
141     SdrGlueEditView::BrkAction();
142 }
143 
144 void SdrObjEditView::TakeActionRect(Rectangle& rRect) const
145 {
146     if (IsMacroObj()) {
147         rRect=pMacroObj->GetCurrentBoundRect();
148     } else {
149         SdrGlueEditView::TakeActionRect(rRect);
150     }
151 }
152 
153 void __EXPORT SdrObjEditView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
154 {
155     SdrGlueEditView::Notify(rBC,rHint);
156     // Printerwechsel waerend des Editierens
157     SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint);
158     if (pSdrHint!=NULL && pTextEditOutliner!=NULL) {
159         SdrHintKind eKind=pSdrHint->GetKind();
160         if (eKind==HINT_REFDEVICECHG) {
161             pTextEditOutliner->SetRefDevice(pMod->GetRefDevice());
162         }
163         if (eKind==HINT_DEFAULTTABCHG) {
164             pTextEditOutliner->SetDefTab(pMod->GetDefaultTabulator());
165         }
166         if (eKind==HINT_DEFFONTHGTCHG) {
167             // ...
168         }
169         if (eKind==HINT_MODELSAVED) { // #43095#
170             pTextEditOutliner->ClearModifyFlag();
171         }
172     }
173 }
174 
175 void SdrObjEditView::ModelHasChanged()
176 {
177     SdrGlueEditView::ModelHasChanged();
178     if (mxTextEditObj.is() && !mxTextEditObj->IsInserted()) SdrEndTextEdit(); // Objekt geloescht
179     // TextEditObj geaendert?
180     if (IsTextEdit()) {
181         SdrTextObj* pTextObj=dynamic_cast<SdrTextObj*>( mxTextEditObj.get() );
182         if (pTextObj!=NULL) {
183             sal_uIntPtr nOutlViewAnz=pTextEditOutliner->GetViewCount();
184             sal_Bool bAreaChg=sal_False;
185             sal_Bool bAnchorChg=sal_False;
186             sal_Bool bColorChg=sal_False;
187             bool bContourFrame=pTextObj->IsContourTextFrame();
188             EVAnchorMode eNewAnchor(ANCHOR_VCENTER_HCENTER);
189             Rectangle aOldArea(aMinTextEditArea);
190             aOldArea.Union(aTextEditArea);
191             Color aNewColor;
192             { // Area Checken
193                 Size aPaperMin1;
194                 Size aPaperMax1;
195                 Rectangle aEditArea1;
196                 Rectangle aMinArea1;
197                 pTextObj->TakeTextEditArea(&aPaperMin1,&aPaperMax1,&aEditArea1,&aMinArea1);
198 
199                 // #108784#
200                 Point aPvOfs(pTextObj->GetTextEditOffset());
201 
202                 aEditArea1.Move(aPvOfs.X(),aPvOfs.Y());
203                 aMinArea1.Move(aPvOfs.X(),aPvOfs.Y());
204                 Rectangle aNewArea(aMinArea1);
205                 aNewArea.Union(aEditArea1);
206 
207                 if (aNewArea!=aOldArea || aEditArea1!=aTextEditArea || aMinArea1!=aMinTextEditArea ||
208                     pTextEditOutliner->GetMinAutoPaperSize()!=aPaperMin1 || pTextEditOutliner->GetMaxAutoPaperSize()!=aPaperMax1) {
209                     aTextEditArea=aEditArea1;
210                     aMinTextEditArea=aMinArea1;
211                     pTextEditOutliner->SetUpdateMode(sal_False);
212                     pTextEditOutliner->SetMinAutoPaperSize(aPaperMin1);
213                     pTextEditOutliner->SetMaxAutoPaperSize(aPaperMax1);
214                     pTextEditOutliner->SetPaperSize(Size(0,0)); // Damit der Outliner neu formatiert
215                     if (!bContourFrame) {
216                         pTextEditOutliner->ClearPolygon();
217                         sal_uIntPtr nStat=pTextEditOutliner->GetControlWord();
218                         nStat|=EE_CNTRL_AUTOPAGESIZE;
219                         pTextEditOutliner->SetControlWord(nStat);
220                     } else {
221                         sal_uIntPtr nStat=pTextEditOutliner->GetControlWord();
222                         nStat&=~EE_CNTRL_AUTOPAGESIZE;
223                         pTextEditOutliner->SetControlWord(nStat);
224                         Rectangle aAnchorRect;
225                         pTextObj->TakeTextAnchorRect(aAnchorRect);
226                         pTextObj->ImpSetContourPolygon(*pTextEditOutliner,aAnchorRect, sal_True);
227                     }
228                     for (sal_uIntPtr nOV=0; nOV<nOutlViewAnz; nOV++) {
229                         OutlinerView* pOLV=pTextEditOutliner->GetView(nOV);
230                         sal_uIntPtr nStat0=pOLV->GetControlWord();
231                         sal_uIntPtr nStat=nStat0;
232                         // AutoViewSize nur wenn nicht KontourFrame.
233                         if (!bContourFrame) nStat|=EV_CNTRL_AUTOSIZE;
234                         else nStat&=~EV_CNTRL_AUTOSIZE;
235                         if (nStat!=nStat0) pOLV->SetControlWord(nStat);
236                     }
237                     pTextEditOutliner->SetUpdateMode(sal_True);
238                     bAreaChg=sal_True;
239                 }
240             }
241             if (pTextEditOutlinerView!=NULL) { // Fuellfarbe und Anker checken
242                 EVAnchorMode eOldAnchor=pTextEditOutlinerView->GetAnchorMode();
243                 eNewAnchor=(EVAnchorMode)pTextObj->GetOutlinerViewAnchorMode();
244                 bAnchorChg=eOldAnchor!=eNewAnchor;
245                 Color aOldColor(pTextEditOutlinerView->GetBackgroundColor());
246                 aNewColor = GetTextEditBackgroundColor(*this);
247                 bColorChg=aOldColor!=aNewColor;
248             }
249             // #104082# refresh always when it's a contour frame. That
250             // refresh is necessary since it triggers the repaint
251             // which makes the Handles visible. Changes at TakeTextRect()
252             // seem to have resulted in a case where no refresh is executed.
253             // Before that, a refresh must have been always executed
254             // (else this error would have happend earlier), thus i
255             // even think here a refresh should be done always.
256             // Since follow-up problems cannot even be guessed I only
257             // add this one more case to the if below.
258             // BTW: It's VERY bad style that here, inside ModelHasChanged()
259             // the outliner is again massively changed for the text object
260             // in text edit mode. Normally, all necessary data should be
261             // set at SdrBeginTextEdit(). Some changes and value assigns in
262             // SdrBeginTextEdit() are completely useless since they are set here
263             // again on ModelHasChanged().
264             if (bContourFrame || bAreaChg || bAnchorChg || bColorChg)
265             {
266                 for (sal_uIntPtr nOV=0; nOV<nOutlViewAnz; nOV++)
267                 {
268                     OutlinerView* pOLV=pTextEditOutliner->GetView(nOV);
269                     { // Alten OutlinerView-Bereich invalidieren
270                         Window* pWin=pOLV->GetWindow();
271                         Rectangle aTmpRect(aOldArea);
272                         sal_uInt16 nPixSiz=pOLV->GetInvalidateMore()+1;
273                         Size aMore(pWin->PixelToLogic(Size(nPixSiz,nPixSiz)));
274                         aTmpRect.Left()-=aMore.Width();
275                         aTmpRect.Right()+=aMore.Width();
276                         aTmpRect.Top()-=aMore.Height();
277                         aTmpRect.Bottom()+=aMore.Height();
278                         InvalidateOneWin(*pWin,aTmpRect);
279                     }
280                     if (bAnchorChg)
281                         pOLV->SetAnchorMode(eNewAnchor);
282                     if (bColorChg)
283                         pOLV->SetBackgroundColor( aNewColor );
284 
285                     pOLV->SetOutputArea(aTextEditArea); // weil sonst scheinbar nicht richtig umgeankert wird
286                     ImpInvalidateOutlinerView(*pOLV);
287                 }
288                 pTextEditOutlinerView->ShowCursor();
289             }
290         }
291         ImpMakeTextCursorAreaVisible();
292     }
293 }
294 
295 ////////////////////////////////////////////////////////////////////////////////////////////////////
296 //
297 //  @@@@@@ @@@@@ @@   @@ @@@@@@  @@@@@ @@@@@  @@ @@@@@@
298 //    @@   @@    @@@ @@@   @@    @@    @@  @@ @@   @@
299 //    @@   @@     @@@@@    @@    @@    @@  @@ @@   @@
300 //    @@   @@@@    @@@     @@    @@@@  @@  @@ @@   @@
301 //    @@   @@     @@@@@    @@    @@    @@  @@ @@   @@
302 //    @@   @@    @@@ @@@   @@    @@    @@  @@ @@   @@
303 //    @@   @@@@@ @@   @@   @@    @@@@@ @@@@@  @@   @@
304 //
305 ////////////////////////////////////////////////////////////////////////////////////////////////////
306 
307 void SdrObjEditView::TextEditDrawing(SdrPaintWindow& rPaintWindow) const
308 {
309     // draw old text edit stuff
310     if(IsTextEdit())
311     {
312         const SdrOutliner* pActiveOutliner = GetTextEditOutliner();
313 
314         if(pActiveOutliner)
315         {
316             const sal_uInt32 nViewAnz(pActiveOutliner->GetViewCount());
317 
318             if(nViewAnz)
319             {
320                 const Region& rRedrawRegion = rPaintWindow.GetRedrawRegion();
321                 const Rectangle aCheckRect(rRedrawRegion.GetBoundRect());
322 
323                 for(sal_uInt32 i(0); i < nViewAnz; i++)
324                 {
325                     OutlinerView* pOLV = pActiveOutliner->GetView(i);
326 
327                     if(pOLV->GetWindow() == &rPaintWindow.GetOutputDevice())
328                     {
329                         ImpPaintOutlinerView(*pOLV, aCheckRect, rPaintWindow.GetTargetOutputDevice());
330                         return;
331                     }
332                 }
333             }
334         }
335     }
336 }
337 
338 void SdrObjEditView::ImpPaintOutlinerView(OutlinerView& rOutlView, const Rectangle& rRect, OutputDevice& rTargetDevice) const
339 {
340     const SdrTextObj* pText = PTR_CAST(SdrTextObj,GetTextEditObject());
341     bool bTextFrame(pText && pText->IsTextFrame());
342     bool bFitToSize(0 != (pTextEditOutliner->GetControlWord() & EE_CNTRL_STRETCHING));
343     bool bModifyMerk(pTextEditOutliner->IsModified()); // #43095#
344     Rectangle aBlankRect(rOutlView.GetOutputArea());
345     aBlankRect.Union(aMinTextEditArea);
346     Rectangle aPixRect(rTargetDevice.LogicToPixel(aBlankRect));
347     aBlankRect.Intersection(rRect);
348     rOutlView.GetOutliner()->SetUpdateMode(sal_True); // Bugfix #22596#
349     rOutlView.Paint(aBlankRect, &rTargetDevice);
350 
351     if(!bModifyMerk)
352     {
353         // #43095#
354         pTextEditOutliner->ClearModifyFlag();
355     }
356 
357     if(bTextFrame && !bFitToSize)
358     {
359         // completely reworked to use primitives; this ensures same look and functionality
360         const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
361         drawinglayer::processor2d::BaseProcessor2D* pProcessor = drawinglayer::processor2d::createProcessor2DFromOutputDevice(
362             rTargetDevice,
363             aViewInformation2D);
364 
365         if(pProcessor)
366         {
367             const bool bMerk(rTargetDevice.IsMapModeEnabled());
368             const basegfx::B2DRange aRange(aPixRect.Left(), aPixRect.Top(), aPixRect.Right(), aPixRect.Bottom());
369             const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
370             const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor());
371             const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01);
372             const sal_uInt16 nPixSiz(rOutlView.GetInvalidateMore() - 1);
373             const drawinglayer::primitive2d::Primitive2DReference xReference(
374                 new drawinglayer::primitive2d::OverlayRectanglePrimitive(
375                     aRange,
376                     aHilightColor.getBColor(),
377                     fTransparence,
378                     std::max(6, nPixSiz - 2), // grow
379                     0.0, // shrink
380                     0.0));
381             const drawinglayer::primitive2d::Primitive2DSequence aSequence(&xReference, 1);
382 
383             rTargetDevice.EnableMapMode(false);
384             pProcessor->process(aSequence);
385             rTargetDevice.EnableMapMode(bMerk);
386             delete pProcessor;
387         }
388     }
389 
390     rOutlView.ShowCursor();
391 }
392 
393 void SdrObjEditView::ImpInvalidateOutlinerView(OutlinerView& rOutlView) const
394 {
395     Window* pWin = rOutlView.GetWindow();
396 
397     if(pWin)
398     {
399         const SdrTextObj* pText = PTR_CAST(SdrTextObj,GetTextEditObject());
400         bool bTextFrame(pText && pText->IsTextFrame());
401         bool bFitToSize(0 != (pTextEditOutliner->GetControlWord() & EE_CNTRL_STRETCHING));
402 
403         if(bTextFrame && !bFitToSize)
404         {
405             Rectangle aBlankRect(rOutlView.GetOutputArea());
406             aBlankRect.Union(aMinTextEditArea);
407             Rectangle aPixRect(pWin->LogicToPixel(aBlankRect));
408             sal_uInt16 nPixSiz(rOutlView.GetInvalidateMore() - 1);
409 
410             aPixRect.Left()--;
411             aPixRect.Top()--;
412             aPixRect.Right()++;
413             aPixRect.Bottom()++;
414 
415             {
416                 // xPixRect Begrenzen, wegen Treiberproblem bei zu weit hinausragenden Pixelkoordinaten
417                 Size aMaxXY(pWin->GetOutputSizePixel());
418                 long a(2 * nPixSiz);
419                 long nMaxX(aMaxXY.Width() + a);
420                 long nMaxY(aMaxXY.Height() + a);
421 
422                 if (aPixRect.Left  ()<-a) aPixRect.Left()=-a;
423                 if (aPixRect.Top   ()<-a) aPixRect.Top ()=-a;
424                 if (aPixRect.Right ()>nMaxX) aPixRect.Right ()=nMaxX;
425                 if (aPixRect.Bottom()>nMaxY) aPixRect.Bottom()=nMaxY;
426             }
427 
428             Rectangle aOuterPix(aPixRect);
429             aOuterPix.Left()-=nPixSiz;
430             aOuterPix.Top()-=nPixSiz;
431             aOuterPix.Right()+=nPixSiz;
432             aOuterPix.Bottom()+=nPixSiz;
433 
434             bool bMerk(pWin->IsMapModeEnabled());
435             pWin->EnableMapMode(sal_False);
436             pWin->Invalidate(aOuterPix);
437             pWin->EnableMapMode(bMerk);
438         }
439     }
440 }
441 
442 OutlinerView* SdrObjEditView::ImpMakeOutlinerView(Window* pWin, sal_Bool /*bNoPaint*/, OutlinerView* pGivenView) const
443 {
444     // Hintergrund
445     Color aBackground(GetTextEditBackgroundColor(*this));
446     SdrTextObj* pText = dynamic_cast< SdrTextObj * >( mxTextEditObj.get() );
447     sal_Bool bTextFrame=pText!=NULL && pText->IsTextFrame();
448     sal_Bool bContourFrame=pText!=NULL && pText->IsContourTextFrame();
449     // OutlinerView erzeugen
450     OutlinerView* pOutlView=pGivenView;
451     pTextEditOutliner->SetUpdateMode(sal_False);
452     if (pOutlView==NULL) pOutlView=new OutlinerView(pTextEditOutliner,pWin);
453     else pOutlView->SetWindow(pWin);
454     // Scrollen verbieten
455     sal_uIntPtr nStat=pOutlView->GetControlWord();
456     nStat&=~EV_CNTRL_AUTOSCROLL;
457     // AutoViewSize nur wenn nicht KontourFrame.
458     if (!bContourFrame) nStat|=EV_CNTRL_AUTOSIZE;
459     if (bTextFrame) {
460         sal_uInt16 nPixSiz=aHdl.GetHdlSize()*2+1;
461         nStat|=EV_CNTRL_INVONEMORE;
462         pOutlView->SetInvalidateMore(nPixSiz);
463     }
464     pOutlView->SetControlWord(nStat);
465     pOutlView->SetBackgroundColor( aBackground );
466     if (pText!=NULL)
467     {
468         pOutlView->SetAnchorMode((EVAnchorMode)(pText->GetOutlinerViewAnchorMode()));
469         pTextEditOutliner->SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)pText->GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
470     }
471     pOutlView->SetOutputArea(aTextEditArea);
472     pTextEditOutliner->SetUpdateMode(sal_True);
473     ImpInvalidateOutlinerView(*pOutlView);
474     return pOutlView;
475 }
476 
477 sal_Bool SdrObjEditView::IsTextEditFrame() const
478 {
479     SdrTextObj* pText = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
480     return pText!=NULL && pText->IsTextFrame();
481 }
482 
483 IMPL_LINK(SdrObjEditView,ImpOutlinerStatusEventHdl,EditStatus*,pEditStat)
484 {
485     if(pTextEditOutliner )
486     {
487         SdrTextObj* pTextObj = dynamic_cast< SdrTextObj * >( mxTextEditObj.get() );
488         if( pTextObj )
489         {
490             pTextObj->onEditOutlinerStatusEvent( pEditStat );
491         }
492     }
493     return 0;
494 }
495 
496 IMPL_LINK(SdrObjEditView,ImpOutlinerCalcFieldValueHdl,EditFieldInfo*,pFI)
497 {
498     bool bOk=false;
499     String& rStr=pFI->GetRepresentation();
500     rStr.Erase();
501     SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
502     if (pTextObj!=NULL) {
503         Color* pTxtCol=NULL;
504         Color* pFldCol=NULL;
505         bOk=pTextObj->CalcFieldValue(pFI->GetField(),pFI->GetPara(),pFI->GetPos(),sal_True,pTxtCol,pFldCol,rStr);
506         if (bOk) {
507             if (pTxtCol!=NULL) {
508                 pFI->SetTxtColor(*pTxtCol);
509                 delete pTxtCol;
510             }
511             if (pFldCol!=NULL) {
512                 pFI->SetFldColor(*pFldCol);
513                 delete pFldCol;
514             } else {
515                 pFI->SetFldColor(Color(COL_LIGHTGRAY)); // kann spaeter (357) raus
516             }
517         }
518     }
519     Outliner& rDrawOutl=pMod->GetDrawOutliner(pTextObj);
520     Link aDrawOutlLink=rDrawOutl.GetCalcFieldValueHdl();
521     if (!bOk && aDrawOutlLink.IsSet()) {
522         aDrawOutlLink.Call(pFI);
523         bOk = (sal_Bool)rStr.Len();
524     }
525     if (!bOk && aOldCalcFieldValueLink.IsSet()) {
526         return aOldCalcFieldValueLink.Call(pFI);
527     }
528     return 0;
529 }
530 
531 IMPL_LINK(SdrObjEditView, EndTextEditHdl, SdrUndoManager*, /*pUndoManager*/)
532 {
533     SdrEndTextEdit();
534     return 0;
535 }
536 
537 SdrUndoManager* SdrObjEditView::getSdrUndoManagerForEnhancedTextEdit() const
538 {
539     // default returns registered UndoManager
540     return GetModel() ? dynamic_cast< SdrUndoManager* >(GetModel()->GetSdrUndoManager()) : 0;
541 }
542 
543 sal_Bool SdrObjEditView::SdrBeginTextEdit(
544     SdrObject* pObj, SdrPageView* pPV, Window* pWin,
545     sal_Bool bIsNewObj, SdrOutliner* pGivenOutliner,
546     OutlinerView* pGivenOutlinerView,
547     sal_Bool bDontDeleteOutliner, sal_Bool bOnlyOneView,
548     sal_Bool bGrabFocus)
549 {
550     SdrEndTextEdit();
551 
552     if( dynamic_cast< SdrTextObj* >( pObj ) == 0 )
553         return sal_False; // currently only possible with text objects
554 
555     if(bGrabFocus && pWin)
556     {
557         // attetion, this call may cause an EndTextEdit() call to this view
558         pWin->GrabFocus(); // to force the cursor into the edit view
559     }
560 
561     bTextEditDontDelete=bDontDeleteOutliner && pGivenOutliner!=NULL;
562     bTextEditOnlyOneView=bOnlyOneView;
563     bTextEditNewObj=bIsNewObj;
564     const sal_uInt32 nWinAnz(PaintWindowCount());
565     sal_uInt32 i;
566     sal_Bool bBrk(sal_False);
567     // Abbruch, wenn kein Objekt angegeben.
568 
569     if(!pObj)
570     {
571         bBrk = sal_True;
572     }
573 
574     if(!bBrk && !pWin)
575     {
576         for(i = 0L; i < nWinAnz && !pWin; i++)
577         {
578             SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
579 
580             if(OUTDEV_WINDOW == pPaintWindow->GetOutputDevice().GetOutDevType())
581             {
582                 pWin = (Window*)(&pPaintWindow->GetOutputDevice());
583             }
584         }
585 
586         // Abbruch, wenn kein Window da.
587         if(!pWin)
588         {
589             bBrk = sal_True;
590         }
591     }
592 
593     if(!bBrk && !pPV)
594     {
595         pPV = GetSdrPageView();
596 
597         // Abbruch, wenn keine PageView zu dem Objekt vorhanden.
598         if(!pPV)
599         {
600             bBrk = sal_True;
601         }
602     }
603 
604     if(pObj && pPV)
605     {
606         // Kein TextEdit an Objekten im gesperrten Layer
607         if(pPV->GetLockedLayers().IsSet(pObj->GetLayer()))
608         {
609             bBrk = sal_True;
610         }
611     }
612 
613     if(pTextEditOutliner)
614     {
615         DBG_ERROR("SdrObjEditView::SdrBeginTextEdit() da stand noch ein alter Outliner rum");
616         delete pTextEditOutliner;
617         pTextEditOutliner = 0L;
618     }
619 
620     if(!bBrk)
621     {
622         pTextEditWin=pWin;
623         pTextEditPV=pPV;
624         mxTextEditObj.reset( pObj );
625         pTextEditOutliner=pGivenOutliner;
626         if (pTextEditOutliner==NULL)
627             pTextEditOutliner = SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, mxTextEditObj->GetModel() );
628 
629         {
630             SvtAccessibilityOptions aOptions;
631             pTextEditOutliner->ForceAutoColor( aOptions.GetIsAutomaticFontColor() );
632         }
633 
634         sal_Bool bEmpty = mxTextEditObj->GetOutlinerParaObject()==NULL;
635 
636         aOldCalcFieldValueLink=pTextEditOutliner->GetCalcFieldValueHdl();
637         // Der FieldHdl muss von SdrBeginTextEdit gesetzt sein, da dor ein UpdateFields gerufen wird.
638         pTextEditOutliner->SetCalcFieldValueHdl(LINK(this,SdrObjEditView,ImpOutlinerCalcFieldValueHdl));
639         pTextEditOutliner->SetBeginPasteOrDropHdl(LINK(this,SdrObjEditView,BeginPasteOrDropHdl));
640         pTextEditOutliner->SetEndPasteOrDropHdl(LINK(this,SdrObjEditView, EndPasteOrDropHdl));
641 
642         // It is just necessary to make the visualized page known. Set it.
643         pTextEditOutliner->setVisualizedPage(pPV ? pPV->GetPage() : 0);
644 
645         pTextEditOutliner->SetTextObjNoInit( dynamic_cast< SdrTextObj* >( mxTextEditObj.get() ) );
646 
647         if(mxTextEditObj->BegTextEdit(*pTextEditOutliner))
648         {
649             SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
650             DBG_ASSERT( pTextObj, "svx::SdrObjEditView::BegTextEdit(), no text object?" );
651             if( !pTextObj )
652                 return sal_False;
653 
654             // #111096# Switch off evtl. running TextAnimation
655             pTextObj->SetTextAnimationAllowed(sal_False);
656 
657             // alten Cursor merken
658             if (pTextEditOutliner->GetViewCount()!=0)
659             {
660                 OutlinerView* pTmpOLV=pTextEditOutliner->RemoveView(sal_uIntPtr(0));
661                 if(pTmpOLV!=NULL && pTmpOLV!=pGivenOutlinerView)
662                     delete pTmpOLV;
663             }
664 
665             // EditArea ueberTakeTextEditArea bestimmen
666             // Das koennte eigentlich entfallen, da TakeTextRect() die Berechnung der aTextEditArea vornimmt
667             // Die aMinTextEditArea muss jedoch wohl auch erfolgen (darum bleibt es voerst drinnen)
668             pTextObj->TakeTextEditArea(NULL,NULL,&aTextEditArea,&aMinTextEditArea);
669 
670             Rectangle aTextRect;
671             Rectangle aAnchorRect;
672             pTextObj->TakeTextRect(*pTextEditOutliner, aTextRect, sal_True,
673                 &aAnchorRect /* #97097# Give sal_True here, not sal_False */);
674 
675             if ( !pTextObj->IsContourTextFrame() )
676             {
677                 // FitToSize erstmal nicht mit ContourFrame
678                 SdrFitToSizeType eFit = pTextObj->GetFitToSize();
679                 if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES)
680                     aTextRect = aAnchorRect;
681             }
682 
683             aTextEditArea = aTextRect;
684 
685             // #108784#
686             Point aPvOfs(pTextObj->GetTextEditOffset());
687 
688             aTextEditArea.Move(aPvOfs.X(),aPvOfs.Y());
689             aMinTextEditArea.Move(aPvOfs.X(),aPvOfs.Y());
690             pTextEditCursorMerker=pWin->GetCursor();
691 
692             aHdl.SetMoveOutside(sal_True);
693 
694             // #i72757#
695             // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
696             // to call AdjustMarkHdl() always.
697             AdjustMarkHdl();
698             // Call <MarkListHasChanged()> as it also handles context changes for sidebar
699             MarkListHasChanged();
700 
701             pTextEditOutlinerView=ImpMakeOutlinerView(pWin,!bEmpty,pGivenOutlinerView);
702 
703             // check if this view is already inserted
704             sal_uIntPtr i2,nCount = pTextEditOutliner->GetViewCount();
705             for( i2 = 0; i2 < nCount; i2++ )
706             {
707                 if( pTextEditOutliner->GetView(i2) == pTextEditOutlinerView )
708                     break;
709             }
710 
711             if( i2 == nCount )
712                 pTextEditOutliner->InsertView(pTextEditOutlinerView,0);
713 
714             aHdl.SetMoveOutside(sal_False);
715             aHdl.SetMoveOutside(sal_True);
716             //OLMRefreshAllIAOManagers();
717 
718             // alle Wins als OutlinerView beim Outliner anmelden
719             if(!bOnlyOneView)
720             {
721                 for(i = 0L; i < nWinAnz; i++)
722                 {
723                     SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
724                     OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
725 
726                     if(&rOutDev != pWin && OUTDEV_WINDOW == rOutDev.GetOutDevType())
727                     {
728                         OutlinerView* pOutlView = ImpMakeOutlinerView((Window*)(&rOutDev), !bEmpty, 0L);
729                         pTextEditOutliner->InsertView(pOutlView, (sal_uInt16)i);
730                     }
731                 }
732             }
733 
734             pTextEditOutlinerView->ShowCursor();
735             pTextEditOutliner->SetStatusEventHdl(LINK(this,SdrObjEditView,ImpOutlinerStatusEventHdl));
736 #ifdef DBG_UTIL
737             if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
738 #endif
739             pTextEditOutliner->ClearModifyFlag();
740 
741             // #71519#, #91453#
742             if(pWin)
743             {
744                 sal_Bool bExtraInvalidate(sal_False);
745 
746                 // #71519#
747                 if(!bExtraInvalidate)
748                 {
749                     SdrFitToSizeType eFit = pTextObj->GetFitToSize();
750                     if(eFit == SDRTEXTFIT_PROPORTIONAL || eFit == SDRTEXTFIT_ALLLINES)
751                         bExtraInvalidate = sal_True;
752                 }
753 
754                 if(bExtraInvalidate)
755                 {
756                     pWin->Invalidate(aTextEditArea);
757                 }
758             }
759 
760             // send HINT_BEGEDIT #99840#
761             if( GetModel() )
762             {
763                 SdrHint aHint(*pTextObj);
764                 aHint.SetKind(HINT_BEGEDIT);
765                 GetModel()->Broadcast(aHint);
766             }
767 
768             pTextEditOutliner->setVisualizedPage(0);
769 
770             if( mxSelectionController.is() )
771                 mxSelectionController->onSelectionHasChanged();
772 
773             if(IsUndoEnabled())
774             {
775                 SdrUndoManager* pSdrUndoManager = getSdrUndoManagerForEnhancedTextEdit();
776 
777                 if(pSdrUndoManager)
778                 {
779                     // we have an outliner, undo manager and it's an EditUndoManager, exchange
780                     // the document undo manager and the default one from the outliner and tell
781                     // it that text edit starts by setting a callback if it needs to end text edit mode.
782                     if(mpOldTextEditUndoManager)
783                     {
784                         // should not happen, delete it since it was probably forgotten somewhere
785                         OSL_ENSURE(false, "Deleting forgotten old TextEditUndoManager, should be checked (!)");
786                         delete mpOldTextEditUndoManager;
787                         mpOldTextEditUndoManager = 0;
788                     }
789 
790                     mpOldTextEditUndoManager = pTextEditOutliner->SetUndoManager(pSdrUndoManager);
791                     pSdrUndoManager->SetEndTextEditHdl(LINK(this, SdrObjEditView, EndTextEditHdl));
792                 }
793                 else
794                 {
795                     OSL_ENSURE(false, "The document undo manager is not derived from SdrUndoManager (!)");
796                 }
797             }
798 
799             return sal_True; // Gut gelaufen, TextEdit laeuft nun
800         }
801         else
802         {
803             bBrk = sal_True;
804             pTextEditOutliner->SetCalcFieldValueHdl(aOldCalcFieldValueLink);
805             pTextEditOutliner->SetBeginPasteOrDropHdl(Link());
806             pTextEditOutliner->SetEndPasteOrDropHdl(Link());
807 
808         }
809     }
810     if (pTextEditOutliner != NULL)
811     {
812         pTextEditOutliner->setVisualizedPage(0);
813     }
814 
815     // wenn hier angekommen, dann ist irgendwas schief gelaufen
816     if(!bDontDeleteOutliner)
817     {
818         if(pGivenOutliner!=NULL)
819         {
820             delete pGivenOutliner;
821             pTextEditOutliner = NULL;
822         }
823         if(pGivenOutlinerView!=NULL)
824         {
825             delete pGivenOutlinerView;
826             pGivenOutlinerView = NULL;
827         }
828     }
829     if( pTextEditOutliner!=NULL )
830     {
831         delete pTextEditOutliner;
832     }
833 
834     pTextEditOutliner=NULL;
835     pTextEditOutlinerView=NULL;
836     mxTextEditObj.reset(0);
837     pTextEditPV=NULL;
838     pTextEditWin=NULL;
839     //HMHif (bMarkHdlWhenTextEdit) {
840     //HMH    HideMarkHdl();
841     //HMH}
842     aHdl.SetMoveOutside(sal_False);
843     //HMHShowMarkHdl();
844 
845     return sal_False;
846 }
847 
848 SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally)
849 {
850     SdrEndTextEditKind eRet=SDRENDTEXTEDIT_UNCHANGED;
851     SdrTextObj* pTEObj = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
852     Window*       pTEWin         =pTextEditWin;
853     SdrOutliner*  pTEOutliner    =pTextEditOutliner;
854     OutlinerView* pTEOutlinerView=pTextEditOutlinerView;
855     Cursor*       pTECursorMerker=pTextEditCursorMerker;
856     SdrUndoManager* pUndoEditUndoManager = 0;
857     bool bNeedToUndoSavedRedoTextEdit(false);
858 
859     if(IsUndoEnabled() && GetModel() && pTEObj && pTEOutliner)
860     {
861         // change back the UndoManager to the remembered original one
862         ::svl::IUndoManager* pOriginal = pTEOutliner->SetUndoManager(mpOldTextEditUndoManager);
863         mpOldTextEditUndoManager = 0;
864 
865         if(pOriginal)
866         {
867             // check if we got back our document undo manager
868             SdrUndoManager* pSdrUndoManager = getSdrUndoManagerForEnhancedTextEdit();
869 
870             if(pSdrUndoManager && dynamic_cast< SdrUndoManager* >(pOriginal) == pSdrUndoManager)
871             {
872                 if(pSdrUndoManager->isEndTextEditTriggeredFromUndo())
873                 {
874                     // remember the UndoManager where missing Undos have to be triggered after end
875                     // text edit. When the undo had triggered the end text edit, the original action
876                     // which had to be undone originally is not yet undone.
877                     pUndoEditUndoManager = pSdrUndoManager;
878 
879                     // We are ending text edit; if text edit was triggered from undo, execute all redos
880                     // to create a complete text change undo action for the redo buffer. Also mark this
881                     // state when at least one redo was executed; the created extra TextChange needs to
882                     // be undone in addition to the first real undo outside the text edit changes
883                     while(pSdrUndoManager->GetRedoActionCount())
884                     {
885                         bNeedToUndoSavedRedoTextEdit = true;
886                         pSdrUndoManager->Redo();
887                     }
888                 }
889 
890                 // reset the callback link and let the undo manager cleanup all text edit
891                 // undo actions to get the stack back to the form before the text edit
892                 pSdrUndoManager->SetEndTextEditHdl(Link());
893             }
894             else
895             {
896                 OSL_ENSURE(false, "�Got UndoManager back in SdrEndTextEdit which is NOT the expected document UndoManager (!)");
897                 delete pOriginal;
898             }
899         }
900     }
901 
902     // send HINT_ENDEDIT #99840#
903     if( GetModel() && mxTextEditObj.is() )
904     {
905         SdrHint aHint(*mxTextEditObj.get());
906         aHint.SetKind(HINT_ENDEDIT);
907         GetModel()->Broadcast(aHint);
908     }
909 
910     mxTextEditObj.reset(0);
911     pTextEditPV=NULL;
912     pTextEditWin=NULL;
913     pTextEditOutliner=NULL;
914     pTextEditOutlinerView=NULL;
915     pTextEditCursorMerker=NULL;
916     aTextEditArea=Rectangle();
917 
918     if (pTEOutliner!=NULL)
919     {
920         sal_Bool bModified=pTEOutliner->IsModified();
921         if (pTEOutlinerView!=NULL)
922         {
923             pTEOutlinerView->HideCursor();
924         }
925         if (pTEObj!=NULL)
926         {
927             pTEOutliner->CompleteOnlineSpelling();
928 
929             SdrUndoObjSetText* pTxtUndo = 0;
930 
931             if( bModified )
932             {
933                 sal_Int32 nText;
934                 for( nText = 0; nText < pTEObj->getTextCount(); ++nText )
935                     if( pTEObj->getText( nText ) == pTEObj->getActiveText() )
936                         break;
937 
938                 pTxtUndo = dynamic_cast< SdrUndoObjSetText* >( GetModel()->GetSdrUndoFactory().CreateUndoObjectSetText(*pTEObj, nText ) );
939             }
940             DBG_ASSERT( !bModified || pTxtUndo, "svx::SdrObjEditView::EndTextEdit(), could not create undo action!" );
941             // Den alten CalcFieldValue-Handler wieder setzen
942             // Muss vor Obj::EndTextEdit() geschehen, da dort ein UpdateFields() gemacht wird.
943             pTEOutliner->SetCalcFieldValueHdl(aOldCalcFieldValueLink);
944             pTEOutliner->SetBeginPasteOrDropHdl(Link());
945             pTEOutliner->SetEndPasteOrDropHdl(Link());
946 
947             const bool bUndo = IsUndoEnabled();
948             if( bUndo )
949             {
950                 XubString aObjName;
951                 pTEObj->TakeObjNameSingul(aObjName);
952                 BegUndo(ImpGetResStr(STR_UndoObjSetText),aObjName);
953             }
954 
955             pTEObj->EndTextEdit(*pTEOutliner);
956 
957             if( (pTEObj->GetRotateAngle() != 0) || (pTEObj && pTEObj->ISA(SdrTextObj) && ((SdrTextObj*)pTEObj)->IsFontwork())  )
958             {
959                 // obviously a repaint
960                 pTEObj->ActionChanged();
961             }
962 
963             if (pTxtUndo!=NULL)
964             {
965                 pTxtUndo->AfterSetText();
966                 if (!pTxtUndo->IsDifferent())
967                 {
968                     delete pTxtUndo;
969                     pTxtUndo=NULL;
970                 }
971             }
972             // Loeschung des gesamten TextObj checken
973             SdrUndoAction* pDelUndo=NULL;
974             sal_Bool bDelObj=sal_False;
975             SdrTextObj* pTextObj=PTR_CAST(SdrTextObj,pTEObj);
976             if (pTextObj!=NULL && bTextEditNewObj)
977             {
978                 bDelObj=pTextObj->IsTextFrame() &&
979                         !pTextObj->HasText() &&
980                         !pTextObj->IsEmptyPresObj() &&
981                         !pTextObj->HasFill() &&
982                         !pTextObj->HasLine();
983 
984                 if(pTEObj->IsInserted() && bDelObj && pTextObj->GetObjInventor()==SdrInventor && !bDontDeleteReally)
985                 {
986                     SdrObjKind eIdent=(SdrObjKind)pTextObj->GetObjIdentifier();
987                     if(eIdent==OBJ_TEXT || eIdent==OBJ_TEXTEXT)
988                     {
989                         pDelUndo= GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pTEObj);
990                     }
991                 }
992             }
993             if (pTxtUndo!=NULL)
994             {
995                 if( bUndo )
996                     AddUndo(pTxtUndo);
997                 eRet=SDRENDTEXTEDIT_CHANGED;
998             }
999             if (pDelUndo!=NULL)
1000             {
1001                 if( bUndo )
1002                 {
1003                     AddUndo(pDelUndo);
1004                 }
1005                 else
1006                 {
1007                     delete pDelUndo;
1008                 }
1009                 eRet=SDRENDTEXTEDIT_DELETED;
1010                 DBG_ASSERT(pTEObj->GetObjList()!=NULL,"SdrObjEditView::SdrEndTextEdit(): Fatal: Editiertes Objekt hat keine ObjList!");
1011                 if (pTEObj->GetObjList()!=NULL)
1012                 {
1013                     pTEObj->GetObjList()->RemoveObject(pTEObj->GetOrdNum());
1014                     CheckMarked(); // und gleich die Maekierung entfernen...
1015                 }
1016             }
1017             else if (bDelObj)
1018             { // Fuer den Writer: Loeschen muss die App nachholen.
1019                 eRet=SDRENDTEXTEDIT_SHOULDBEDELETED;
1020             }
1021 
1022             if( bUndo )
1023                 EndUndo(); // EndUndo hinter Remove, falls der UndoStack gleich weggehaun' wird
1024 
1025             // #111096#
1026             // Switch on evtl. TextAnimation again after TextEdit
1027             if(pTEObj->ISA(SdrTextObj))
1028             {
1029                 ((SdrTextObj*)pTEObj)->SetTextAnimationAllowed(sal_True);
1030             }
1031 
1032             // #i72757#
1033             // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
1034             // to call AdjustMarkHdl() always.
1035             AdjustMarkHdl();
1036             // Call <MarkListHasChanged()> as it also handles context changes for sidebar
1037             MarkListHasChanged();
1038         }
1039         // alle OutlinerViews loeschen
1040         for (sal_uIntPtr i=pTEOutliner->GetViewCount(); i>0;)
1041         {
1042             i--;
1043             OutlinerView* pOLV=pTEOutliner->GetView(i);
1044             sal_uInt16 nMorePix=pOLV->GetInvalidateMore() + 10; // solaris aw033 test #i#
1045             Window* pWin=pOLV->GetWindow();
1046             Rectangle aRect(pOLV->GetOutputArea());
1047             pTEOutliner->RemoveView(i);
1048             if (!bTextEditDontDelete || i!=0)
1049             {
1050                 // die nullte gehoert mir u.U. nicht.
1051                 delete pOLV;
1052             }
1053             aRect.Union(aTextEditArea);
1054             aRect.Union(aMinTextEditArea);
1055             aRect=pWin->LogicToPixel(aRect);
1056             aRect.Left()-=nMorePix;
1057             aRect.Top()-=nMorePix;
1058             aRect.Right()+=nMorePix;
1059             aRect.Bottom()+=nMorePix;
1060             aRect=pWin->PixelToLogic(aRect);
1061             InvalidateOneWin(*pWin,aRect);
1062 //          pWin->Invalidate(INVALIDATE_UPDATE);
1063 
1064 //          pWin->Update();
1065 //          pWin->Flush();
1066             pWin->SetFillColor();
1067             pWin->SetLineColor(COL_BLACK);
1068             pWin->DrawPixel(aRect.TopLeft());
1069             pWin->DrawPixel(aRect.TopRight());
1070             pWin->DrawPixel(aRect.BottomLeft());
1071             pWin->DrawPixel(aRect.BottomRight());
1072             //pWin->DrawRect(aRect);
1073         }
1074         // und auch den Outliner selbst
1075         if (!bTextEditDontDelete) delete pTEOutliner;
1076         else pTEOutliner->Clear();
1077         if (pTEWin!=NULL) {
1078             pTEWin->SetCursor(pTECursorMerker);
1079         }
1080 //HMH        if (bMarkHdlWhenTextEdit) {
1081 //HMH            HideMarkHdl();
1082 //HMH        }
1083         aHdl.SetMoveOutside(sal_False);
1084         if (eRet!=SDRENDTEXTEDIT_UNCHANGED)
1085 //HMH       {
1086 //HMH            ShowMarkHdl(); // Handles kommen ansonsten via Broadcast
1087 //HMH        }
1088 //HMH       else
1089         {
1090             GetMarkedObjectListWriteAccess().SetNameDirty();
1091         }
1092 #ifdef DBG_UTIL
1093         if (pItemBrowser)
1094         {
1095             GetMarkedObjectListWriteAccess().SetNameDirty();
1096             pItemBrowser->SetDirty();
1097         }
1098 #endif
1099     }
1100 
1101     // #108784#
1102     if( pTEObj &&
1103         pTEObj->GetModel() &&
1104         !pTEObj->GetModel()->isLocked() &&
1105         pTEObj->GetBroadcaster())
1106     {
1107         SdrHint aHint(HINT_ENDEDIT);
1108         aHint.SetObject(pTEObj);
1109         ((SfxBroadcaster*)pTEObj->GetBroadcaster())->Broadcast(aHint);
1110     }
1111 
1112     if(pUndoEditUndoManager)
1113     {
1114         if(bNeedToUndoSavedRedoTextEdit)
1115         {
1116             // undo the text edit action since it was created as part of an EndTextEdit
1117             // callback from undo itself. This needs to be done after the call to
1118             // FmFormView::SdrEndTextEdit since it gets created there
1119             pUndoEditUndoManager->Undo();
1120         }
1121 
1122         // trigger the Undo which was not executed, but lead to this
1123         // end text edit
1124         pUndoEditUndoManager->Undo();
1125     }
1126 
1127     return eRet;
1128 }
1129 
1130 ////////////////////////////////////////////////////////////////////////////////////////////////////
1131 // info about TextEdit. Default is sal_False.
1132 bool SdrObjEditView::IsTextEdit() const
1133 {
1134     return mxTextEditObj.is();
1135 }
1136 
1137 // info about TextEditPageView. Default is 0L.
1138 SdrPageView* SdrObjEditView::GetTextEditPageView() const
1139 {
1140     return pTextEditPV;
1141 }
1142 
1143 ////////////////////////////////////////////////////////////////////////////////////////////////////
1144 
1145 OutlinerView* SdrObjEditView::ImpFindOutlinerView(Window* pWin) const
1146 {
1147     if (pWin==NULL) return NULL;
1148     if (pTextEditOutliner==NULL) return NULL;
1149     OutlinerView* pNewView=NULL;
1150     sal_uIntPtr nWinAnz=pTextEditOutliner->GetViewCount();
1151     for (sal_uIntPtr i=0; i<nWinAnz && pNewView==NULL; i++) {
1152         OutlinerView* pView=pTextEditOutliner->GetView(i);
1153         if (pView->GetWindow()==pWin) pNewView=pView;
1154     }
1155     return pNewView;
1156 }
1157 
1158 void SdrObjEditView::SetTextEditWin(Window* pWin)
1159 {
1160     if(mxTextEditObj.is() && pWin!=NULL && pWin!=pTextEditWin)
1161     {
1162         OutlinerView* pNewView=ImpFindOutlinerView(pWin);
1163         if (pNewView!=NULL && pNewView!=pTextEditOutlinerView)
1164         {
1165             if (pTextEditOutlinerView!=NULL)
1166             {
1167                 pTextEditOutlinerView->HideCursor();
1168             }
1169             pTextEditOutlinerView=pNewView;
1170             pTextEditWin=pWin;
1171             pWin->GrabFocus(); // Damit der Cursor hier auch blinkt
1172             pNewView->ShowCursor();
1173             ImpMakeTextCursorAreaVisible();
1174         }
1175     }
1176 }
1177 
1178 sal_Bool SdrObjEditView::IsTextEditHit(const Point& rHit, short nTol) const
1179 {
1180     sal_Bool bOk=sal_False;
1181     if(mxTextEditObj.is())
1182     {
1183         nTol=ImpGetHitTolLogic(nTol,NULL);
1184         // nur drittel Toleranz hier, damit die Handles
1185         // noch vernuenftig getroffen werden koennen
1186         nTol=nTol/3;
1187         nTol=0; // Joe am 6.3.1997: Keine Hittoleranz mehr hier
1188         if (!bOk)
1189         {
1190             Rectangle aEditArea;
1191             OutlinerView* pOLV=pTextEditOutliner->GetView(0);
1192             if (pOLV!=NULL)
1193             {
1194                 aEditArea.Union(pOLV->GetOutputArea());
1195             }
1196             aEditArea.Left()-=nTol;
1197             aEditArea.Top()-=nTol;
1198             aEditArea.Right()+=nTol;
1199             aEditArea.Bottom()+=nTol;
1200             bOk=aEditArea.IsInside(rHit);
1201             if (bOk)
1202             { // Nun noch checken, ob auch wirklich Buchstaben getroffen wurden
1203                 Point aPnt(rHit); aPnt-=aEditArea.TopLeft();
1204                 long nHitTol = 2000;
1205                 OutputDevice* pRef = pTextEditOutliner->GetRefDevice();
1206                 if( pRef )
1207                     nHitTol = pRef->LogicToLogic( nHitTol, MAP_100TH_MM, pRef->GetMapMode().GetMapUnit() );
1208 
1209                 bOk = pTextEditOutliner->IsTextPos( aPnt, (sal_uInt16)nHitTol );
1210             }
1211         }
1212     }
1213     return bOk;
1214 }
1215 
1216 sal_Bool SdrObjEditView::IsTextEditFrameHit(const Point& rHit) const
1217 {
1218     sal_Bool bOk=sal_False;
1219     if(mxTextEditObj.is())
1220     {
1221         SdrTextObj* pText= dynamic_cast<SdrTextObj*>(mxTextEditObj.get());
1222         OutlinerView* pOLV=pTextEditOutliner->GetView(0);
1223         if( pOLV )
1224         {
1225             Window* pWin=pOLV->GetWindow();
1226             if (pText!=NULL && pText->IsTextFrame() && pOLV!=NULL && pWin!=NULL) {
1227                 sal_uInt16 nPixSiz=pOLV->GetInvalidateMore();
1228                 Rectangle aEditArea(aMinTextEditArea);
1229                 aEditArea.Union(pOLV->GetOutputArea());
1230                 if (!aEditArea.IsInside(rHit)) {
1231                     Size aSiz(pWin->PixelToLogic(Size(nPixSiz,nPixSiz)));
1232                     aEditArea.Left()-=aSiz.Width();
1233                     aEditArea.Top()-=aSiz.Height();
1234                     aEditArea.Right()+=aSiz.Width();
1235                     aEditArea.Bottom()+=aSiz.Height();
1236                     bOk=aEditArea.IsInside(rHit);
1237                 }
1238             }
1239         }
1240     }
1241     return bOk;
1242 }
1243 
1244 void SdrObjEditView::AddTextEditOfs(MouseEvent& rMEvt) const
1245 {
1246     if(mxTextEditObj.is())
1247     {
1248         Point aPvOfs;
1249         SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
1250 
1251         if( pTextObj )
1252         {
1253             // #108784#
1254             aPvOfs += pTextObj->GetTextEditOffset();
1255         }
1256 
1257         Point aObjOfs(mxTextEditObj->GetLogicRect().TopLeft());
1258         (Point&)(rMEvt.GetPosPixel())+=aPvOfs+aObjOfs;
1259     }
1260 }
1261 
1262 ////////////////////////////////////////////////////////////////////////////////////////////////////
1263 
1264 sal_Bool SdrObjEditView::KeyInput(const KeyEvent& rKEvt, Window* pWin)
1265 {
1266     if(pTextEditOutlinerView)
1267     {
1268 #ifdef DBG_UTIL
1269         if(rKEvt.GetKeyCode().GetCode() == KEY_RETURN && pTextEditOutliner->GetParagraphCount() == 1)
1270         {
1271             ByteString aLine(
1272                 pTextEditOutliner->GetText(pTextEditOutliner->GetParagraph( 0 ), 1),
1273                 gsl_getSystemTextEncoding());
1274             aLine = aLine.ToUpperAscii();
1275 
1276             if(aLine == "HELLO JOE, PLEASE SHOW THE ITEMBROWSER")
1277                 ShowItemBrowser();
1278         }
1279 #endif
1280         if (pTextEditOutlinerView->PostKeyEvent(rKEvt))
1281         {
1282             if( pMod /* && !pMod->IsChanged() */ )
1283             {
1284                 if( pTextEditOutliner && pTextEditOutliner->IsModified() )
1285                     pMod->SetChanged( sal_True );
1286             }
1287 
1288             if (pWin!=NULL && pWin!=pTextEditWin) SetTextEditWin(pWin);
1289 #ifdef DBG_UTIL
1290             if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1291 #endif
1292             ImpMakeTextCursorAreaVisible();
1293             return sal_True;
1294         }
1295     }
1296     return SdrGlueEditView::KeyInput(rKEvt,pWin);
1297 }
1298 
1299 sal_Bool SdrObjEditView::MouseButtonDown(const MouseEvent& rMEvt, Window* pWin)
1300 {
1301     if (pTextEditOutlinerView!=NULL) {
1302         sal_Bool bPostIt=pTextEditOutliner->IsInSelectionMode();
1303         if (!bPostIt) {
1304             Point aPt(rMEvt.GetPosPixel());
1305             if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
1306             else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
1307             bPostIt=IsTextEditHit(aPt,nHitTolLog);
1308         }
1309         if (bPostIt) {
1310             Point aPixPos(rMEvt.GetPosPixel());
1311             Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
1312             if (aPixPos.X()<aR.Left  ()) aPixPos.X()=aR.Left  ();
1313             if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
1314             if (aPixPos.Y()<aR.Top   ()) aPixPos.Y()=aR.Top   ();
1315             if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
1316             MouseEvent aMEvt(aPixPos,rMEvt.GetClicks(),rMEvt.GetMode(),
1317                              rMEvt.GetButtons(),rMEvt.GetModifier());
1318             if (pTextEditOutlinerView->MouseButtonDown(aMEvt)) {
1319                 if (pWin!=NULL && pWin!=pTextEditWin) SetTextEditWin(pWin);
1320 #ifdef DBG_UTIL
1321                 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1322 #endif
1323                 ImpMakeTextCursorAreaVisible();
1324                 return sal_True;
1325             }
1326         }
1327     }
1328     return SdrGlueEditView::MouseButtonDown(rMEvt,pWin);
1329 }
1330 
1331 sal_Bool SdrObjEditView::MouseButtonUp(const MouseEvent& rMEvt, Window* pWin)
1332 {
1333     if (pTextEditOutlinerView!=NULL) {
1334         sal_Bool bPostIt=pTextEditOutliner->IsInSelectionMode();
1335         if (!bPostIt) {
1336             Point aPt(rMEvt.GetPosPixel());
1337             if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
1338             else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
1339             bPostIt=IsTextEditHit(aPt,nHitTolLog);
1340         }
1341         if (bPostIt) {
1342             Point aPixPos(rMEvt.GetPosPixel());
1343             Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
1344             if (aPixPos.X()<aR.Left  ()) aPixPos.X()=aR.Left  ();
1345             if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
1346             if (aPixPos.Y()<aR.Top   ()) aPixPos.Y()=aR.Top   ();
1347             if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
1348             MouseEvent aMEvt(aPixPos,rMEvt.GetClicks(),rMEvt.GetMode(),
1349                              rMEvt.GetButtons(),rMEvt.GetModifier());
1350             if (pTextEditOutlinerView->MouseButtonUp(aMEvt)) {
1351 #ifdef DBG_UTIL
1352                 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1353 #endif
1354                 ImpMakeTextCursorAreaVisible();
1355                 return sal_True;
1356             }
1357         }
1358     }
1359     return SdrGlueEditView::MouseButtonUp(rMEvt,pWin);
1360 }
1361 
1362 sal_Bool SdrObjEditView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
1363 {
1364     if (pTextEditOutlinerView!=NULL) {
1365         sal_Bool bSelMode=pTextEditOutliner->IsInSelectionMode();
1366         sal_Bool bPostIt=bSelMode;
1367         if (!bPostIt) {
1368             Point aPt(rMEvt.GetPosPixel());
1369             if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
1370             else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
1371             bPostIt=IsTextEditHit(aPt,nHitTolLog);
1372         }
1373         if (bPostIt) {
1374             Point aPixPos(rMEvt.GetPosPixel());
1375             Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
1376             if (aPixPos.X()<aR.Left  ()) aPixPos.X()=aR.Left  ();
1377             if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
1378             if (aPixPos.Y()<aR.Top   ()) aPixPos.Y()=aR.Top   ();
1379             if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
1380             MouseEvent aMEvt(aPixPos,rMEvt.GetClicks(),rMEvt.GetMode(),
1381                              rMEvt.GetButtons(),rMEvt.GetModifier());
1382             if (pTextEditOutlinerView->MouseMove(aMEvt) && bSelMode) {
1383 #ifdef DBG_UTIL
1384                 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1385 #endif
1386                 ImpMakeTextCursorAreaVisible();
1387                 return sal_True;
1388             }
1389         }
1390     }
1391     return SdrGlueEditView::MouseMove(rMEvt,pWin);
1392 }
1393 
1394 sal_Bool SdrObjEditView::Command(const CommandEvent& rCEvt, Window* pWin)
1395 {
1396     // solange bis die OutlinerView einen sal_Bool zurueckliefert
1397     // bekommt sie nur COMMAND_STARTDRAG
1398     if (pTextEditOutlinerView!=NULL)
1399     {
1400         if (rCEvt.GetCommand()==COMMAND_STARTDRAG) {
1401             sal_Bool bPostIt=pTextEditOutliner->IsInSelectionMode() || !rCEvt.IsMouseEvent();
1402             if (!bPostIt && rCEvt.IsMouseEvent()) {
1403                 Point aPt(rCEvt.GetMousePosPixel());
1404                 if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
1405                 else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
1406                 bPostIt=IsTextEditHit(aPt,nHitTolLog);
1407             }
1408             if (bPostIt) {
1409                 Point aPixPos(rCEvt.GetMousePosPixel());
1410                 if (rCEvt.IsMouseEvent()) {
1411                     Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
1412                     if (aPixPos.X()<aR.Left  ()) aPixPos.X()=aR.Left  ();
1413                     if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
1414                     if (aPixPos.Y()<aR.Top   ()) aPixPos.Y()=aR.Top   ();
1415                     if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
1416                 }
1417                 CommandEvent aCEvt(aPixPos,rCEvt.GetCommand(),rCEvt.IsMouseEvent());
1418                 // Command ist an der OutlinerView leider void
1419                 pTextEditOutlinerView->Command(aCEvt);
1420                 if (pWin!=NULL && pWin!=pTextEditWin) SetTextEditWin(pWin);
1421 #ifdef DBG_UTIL
1422                 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1423 #endif
1424                 ImpMakeTextCursorAreaVisible();
1425                 return sal_True;
1426             }
1427         }
1428         else // if (rCEvt.GetCommand() == COMMAND_VOICE )
1429         {
1430             pTextEditOutlinerView->Command(rCEvt);
1431             return sal_True;
1432         }
1433     }
1434     return SdrGlueEditView::Command(rCEvt,pWin);
1435 }
1436 
1437 sal_Bool SdrObjEditView::Cut(sal_uIntPtr nFormat)
1438 {
1439     if (pTextEditOutliner!=NULL) {
1440         pTextEditOutlinerView->Cut();
1441 #ifdef DBG_UTIL
1442         if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1443 #endif
1444         ImpMakeTextCursorAreaVisible();
1445         return sal_True;
1446     } else {
1447         return SdrGlueEditView::Cut(nFormat);
1448     }
1449 }
1450 
1451 sal_Bool SdrObjEditView::Yank(sal_uIntPtr nFormat)
1452 {
1453     if (pTextEditOutliner!=NULL) {
1454         pTextEditOutlinerView->Copy();
1455         return sal_True;
1456     } else {
1457         return SdrGlueEditView::Yank(nFormat);
1458     }
1459 }
1460 
1461 sal_Bool SdrObjEditView::Paste(Window* pWin, sal_uIntPtr nFormat)
1462 {
1463     if (pTextEditOutliner!=NULL) {
1464         if (pWin!=NULL) {
1465             OutlinerView* pNewView=ImpFindOutlinerView(pWin);
1466             if (pNewView!=NULL) {
1467                 pNewView->Paste();
1468             }
1469         } else {
1470             pTextEditOutlinerView->Paste();
1471         }
1472 #ifdef DBG_UTIL
1473         if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1474 #endif
1475         ImpMakeTextCursorAreaVisible();
1476         return sal_True;
1477     } else {
1478         return SdrGlueEditView::Paste(pWin,nFormat);
1479     }
1480 }
1481 
1482 ////////////////////////////////////////////////////////////////////////////////////////////////////
1483 
1484 sal_Bool SdrObjEditView::ImpIsTextEditAllSelected() const
1485 {
1486     sal_Bool bRet=sal_False;
1487     if (pTextEditOutliner!=NULL && pTextEditOutlinerView!=NULL)
1488     {
1489         if(SdrTextObj::HasTextImpl( pTextEditOutliner ) )
1490         {
1491             const sal_uInt32 nParaAnz=pTextEditOutliner->GetParagraphCount();
1492             Paragraph* pLastPara=pTextEditOutliner->GetParagraph( nParaAnz > 1 ? nParaAnz - 1 : 0 );
1493 
1494             ESelection aESel(pTextEditOutlinerView->GetSelection());
1495             if (aESel.nStartPara==0 && aESel.nStartPos==0 && aESel.nEndPara==sal_uInt16(nParaAnz-1))
1496             {
1497                 XubString aStr(pTextEditOutliner->GetText(pLastPara));
1498 
1499                 if(aStr.Len() == aESel.nEndPos)
1500                     bRet = sal_True;
1501             }
1502             // und nun auch noch fuer den Fall, das rueckwaerts selektiert wurde
1503             if (!bRet && aESel.nEndPara==0 && aESel.nEndPos==0 && aESel.nStartPara==sal_uInt16(nParaAnz-1))
1504             {
1505                 XubString aStr(pTextEditOutliner->GetText(pLastPara));
1506 
1507                 if(aStr.Len() == aESel.nStartPos)
1508                     bRet = sal_True;
1509             }
1510         }
1511         else
1512         {
1513             bRet=sal_True;
1514         }
1515     }
1516     return bRet;
1517 }
1518 
1519 void SdrObjEditView::ImpMakeTextCursorAreaVisible()
1520 {
1521     if (pTextEditOutlinerView!=NULL && pTextEditWin!=NULL) {
1522         Cursor* pCsr=pTextEditWin->GetCursor();
1523         if (pCsr!=NULL) {
1524             Size aSiz(pCsr->GetSize());
1525             if (aSiz.Width()!=0 && aSiz.Height()!=0) { // #38450#
1526                 MakeVisible(Rectangle(pCsr->GetPos(),aSiz),*pTextEditWin);
1527             }
1528         }
1529     }
1530 }
1531 
1532 sal_uInt16 SdrObjEditView::GetScriptType() const
1533 {
1534     sal_uInt16 nScriptType = 0;
1535 
1536     if( IsTextEdit() )
1537     {
1538         if( mxTextEditObj->GetOutlinerParaObject() )
1539             nScriptType = mxTextEditObj->GetOutlinerParaObject()->GetTextObject().GetScriptType();
1540 
1541         if( pTextEditOutlinerView )
1542             nScriptType = pTextEditOutlinerView->GetSelectedScriptType();
1543     }
1544     else
1545     {
1546         sal_uInt32 nMarkCount( GetMarkedObjectCount() );
1547 
1548         for( sal_uInt32 i = 0; i < nMarkCount; i++ )
1549         {
1550             OutlinerParaObject* pParaObj = GetMarkedObjectByIndex( i )->GetOutlinerParaObject();
1551 
1552             if( pParaObj )
1553             {
1554                 nScriptType |= pParaObj->GetTextObject().GetScriptType();
1555             }
1556         }
1557     }
1558 
1559     if( nScriptType == 0 )
1560         nScriptType = SCRIPTTYPE_LATIN;
1561 
1562     return nScriptType;
1563 }
1564 
1565 /* new interface src537 */
1566 sal_Bool SdrObjEditView::GetAttributes(SfxItemSet& rTargetSet, sal_Bool bOnlyHardAttr) const
1567 {
1568     if( mxSelectionController.is() )
1569         if( mxSelectionController->GetAttributes( rTargetSet, bOnlyHardAttr ) )
1570             return sal_True;
1571 
1572     if(IsTextEdit())
1573     {
1574         DBG_ASSERT(pTextEditOutlinerView!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
1575         DBG_ASSERT(pTextEditOutliner!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
1576 
1577         // #92389# take care of bOnlyHardAttr(!)
1578         if(!bOnlyHardAttr && mxTextEditObj->GetStyleSheet())
1579             rTargetSet.Put(mxTextEditObj->GetStyleSheet()->GetItemSet());
1580 
1581         // add object attributes
1582         rTargetSet.Put( mxTextEditObj->GetMergedItemSet() );
1583 
1584         if( mxTextEditObj->GetOutlinerParaObject() )
1585             rTargetSet.Put( SvxScriptTypeItem( mxTextEditObj->GetOutlinerParaObject()->GetTextObject().GetScriptType() ) );
1586 
1587         if(pTextEditOutlinerView)
1588         {
1589             // FALSE= InvalidItems nicht al Default, sondern als "Loecher" betrachten
1590             rTargetSet.Put(pTextEditOutlinerView->GetAttribs(), sal_False);
1591             rTargetSet.Put( SvxScriptTypeItem( pTextEditOutlinerView->GetSelectedScriptType() ), sal_False );
1592         }
1593 
1594         if(GetMarkedObjectCount()==1 && GetMarkedObjectByIndex(0)==mxTextEditObj.get())
1595         {
1596             MergeNotPersistAttrFromMarked(rTargetSet, bOnlyHardAttr);
1597         }
1598 
1599         return sal_True;
1600     }
1601     else
1602     {
1603         return SdrGlueEditView::GetAttributes(rTargetSet, bOnlyHardAttr);
1604     }
1605 }
1606 
1607 sal_Bool SdrObjEditView::SetAttributes(const SfxItemSet& rSet, sal_Bool bReplaceAll)
1608 {
1609     sal_Bool bRet=sal_False;
1610     sal_Bool bTextEdit=pTextEditOutlinerView!=NULL && mxTextEditObj.is();
1611     sal_Bool bAllTextSelected=ImpIsTextEditAllSelected();
1612     SfxItemSet* pModifiedSet=NULL;
1613     const SfxItemSet* pSet=&rSet;
1614     //const SvxAdjustItem* pParaJust=NULL;
1615 
1616     if (!bTextEdit)
1617     {
1618         // Kein TextEdit aktiv -> alle Items ans Zeichenobjekt
1619         if( mxSelectionController.is() )
1620             bRet=mxSelectionController->SetAttributes(*pSet,bReplaceAll );
1621 
1622         if( !bRet )
1623         {
1624             bRet=SdrGlueEditView::SetAttributes(*pSet,bReplaceAll);
1625         }
1626     }
1627     else
1628     {
1629 #ifdef DBG_UTIL
1630         {
1631             sal_Bool bHasEEFeatureItems=sal_False;
1632             SfxItemIter aIter(rSet);
1633             const SfxPoolItem* pItem=aIter.FirstItem();
1634             while (!bHasEEFeatureItems && pItem!=NULL)
1635             {
1636                 if (!IsInvalidItem(pItem))
1637                 {
1638                     sal_uInt16 nW=pItem->Which();
1639                     if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END)
1640                         bHasEEFeatureItems=sal_True;
1641                 }
1642 
1643                 pItem=aIter.NextItem();
1644             }
1645 
1646             if(bHasEEFeatureItems)
1647             {
1648                 String aMessage;
1649                 aMessage.AppendAscii("SdrObjEditView::SetAttributes(): Das setzen von EE_FEATURE-Items an der SdrView macht keinen Sinn! Es fuehrt nur zu Overhead und nicht mehr lesbaren Dokumenten.");
1650                 InfoBox(NULL, aMessage).Execute();
1651             }
1652         }
1653 #endif
1654 
1655         sal_Bool bOnlyEEItems;
1656         sal_Bool bNoEEItems=!SearchOutlinerItems(*pSet,bReplaceAll,&bOnlyEEItems);
1657         // alles selektiert? -> Attrs auch an den Rahmen
1658         // und falls keine EEItems, dann Attrs nur an den Rahmen
1659         if (bAllTextSelected || bNoEEItems)
1660         {
1661             if( mxSelectionController.is() )
1662                 bRet=mxSelectionController->SetAttributes(*pSet,bReplaceAll );
1663 
1664             if( !bRet )
1665             {
1666                 const bool bUndo = IsUndoEnabled();
1667 
1668                 if( bUndo )
1669                 {
1670                     String aStr;
1671                     ImpTakeDescriptionStr(STR_EditSetAttributes,aStr);
1672                     BegUndo(aStr);
1673                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj.get()));
1674 
1675                     // #i43537#
1676                     // If this is a text object also rescue the OutlinerParaObject since
1677                     // applying attributes to the object may change text layout when
1678                     // multiple portions exist with multiple formats. If a OutlinerParaObject
1679                     // really exists and needs to be rescued is evaluated in the undo
1680                     // implementation itself.
1681                     bool bRescueText = dynamic_cast< SdrTextObj* >(mxTextEditObj.get());
1682 
1683                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*mxTextEditObj.get(),false,!bNoEEItems || bRescueText));
1684                     EndUndo();
1685                 }
1686 
1687                 mxTextEditObj->SetMergedItemSetAndBroadcast(*pSet, bReplaceAll);
1688 
1689                 FlushComeBackTimer(); // Damit ModeHasChanged sofort kommt
1690                 bRet=sal_True;
1691             }
1692         }
1693         else if (!bOnlyEEItems)
1694         {
1695             // sonst Set ggf. splitten
1696             // Es wird nun ein ItemSet aSet gemacht, in den die EE_Items von
1697             // *pSet nicht enhalten ist (ansonsten ist es eine Kopie).
1698             sal_uInt16* pNewWhichTable=RemoveWhichRange(pSet->GetRanges(),EE_ITEMS_START,EE_ITEMS_END);
1699             SfxItemSet aSet(pMod->GetItemPool(),pNewWhichTable);
1700             /*90353*/ delete[] pNewWhichTable;
1701             SfxWhichIter aIter(aSet);
1702             sal_uInt16 nWhich=aIter.FirstWhich();
1703             while (nWhich!=0)
1704             {
1705                 const SfxPoolItem* pItem;
1706                 SfxItemState eState=pSet->GetItemState(nWhich,sal_False,&pItem);
1707                 if (eState==SFX_ITEM_SET) aSet.Put(*pItem);
1708                 nWhich=aIter.NextWhich();
1709             }
1710 
1711 
1712             if( mxSelectionController.is() )
1713                 bRet=mxSelectionController->SetAttributes(aSet,bReplaceAll );
1714 
1715             if( !bRet )
1716             {
1717                 if( IsUndoEnabled() )
1718                 {
1719                     String aStr;
1720                     ImpTakeDescriptionStr(STR_EditSetAttributes,aStr);
1721                     BegUndo(aStr);
1722                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj.get()));
1723                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*mxTextEditObj.get(),false,false));
1724                     EndUndo();
1725                 }
1726 
1727                 mxTextEditObj->SetMergedItemSetAndBroadcast(aSet, bReplaceAll);
1728 
1729                 if (GetMarkedObjectCount()==1 && GetMarkedObjectByIndex(0)==mxTextEditObj.get())
1730                 {
1731                     SetNotPersistAttrToMarked(aSet,bReplaceAll);
1732                 }
1733             }
1734             FlushComeBackTimer();
1735             bRet=sal_True;
1736         }
1737         if(!bNoEEItems)
1738         {
1739             // und nun die Attribute auch noch an die EditEngine
1740             if (bReplaceAll) {
1741                 // Am Outliner kann man leider nur alle Attribute platthauen
1742                 pTextEditOutlinerView->RemoveAttribs( sal_True );
1743             }
1744             pTextEditOutlinerView->SetAttribs(rSet);
1745 
1746 #ifdef DBG_UTIL
1747             if (pItemBrowser!=NULL)
1748                 pItemBrowser->SetDirty();
1749 #endif
1750 
1751             ImpMakeTextCursorAreaVisible();
1752         }
1753         bRet=sal_True;
1754     }
1755     if (pModifiedSet!=NULL)
1756         delete pModifiedSet;
1757     return bRet;
1758 }
1759 
1760 SfxStyleSheet* SdrObjEditView::GetStyleSheet() const
1761 {
1762     SfxStyleSheet* pSheet = 0;
1763 
1764     if( mxSelectionController.is() )
1765     {
1766         if( mxSelectionController->GetStyleSheet( pSheet ) )
1767             return pSheet;
1768     }
1769 
1770     if ( pTextEditOutlinerView )
1771     {
1772         pSheet = pTextEditOutlinerView->GetStyleSheet();
1773     }
1774     else
1775     {
1776         pSheet = SdrGlueEditView::GetStyleSheet();
1777     }
1778     return pSheet;
1779 }
1780 
1781 sal_Bool SdrObjEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr)
1782 {
1783     if( mxSelectionController.is() )
1784     {
1785         if( mxSelectionController->SetStyleSheet( pStyleSheet, bDontRemoveHardAttr ) )
1786             return sal_True;
1787     }
1788 
1789     // if we are currently in edit mode we must also set the stylesheet
1790     // on all paragraphs in the Outliner for the edit view
1791     // #92191#
1792     if( NULL != pTextEditOutlinerView )
1793     {
1794         Outliner* pOutliner = pTextEditOutlinerView->GetOutliner();
1795 
1796         const sal_uIntPtr nParaCount = pOutliner->GetParagraphCount();
1797         sal_uIntPtr nPara;
1798         for( nPara = 0; nPara < nParaCount; nPara++ )
1799         {
1800             pOutliner->SetStyleSheet( nPara, pStyleSheet );
1801         }
1802     }
1803 
1804     return SdrGlueEditView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
1805 }
1806 
1807 ////////////////////////////////////////////////////////////////////////////////////////////////////
1808 
1809 void SdrObjEditView::AddWindowToPaintView(OutputDevice* pNewWin)
1810 {
1811     SdrGlueEditView::AddWindowToPaintView(pNewWin);
1812 
1813     if(mxTextEditObj.is() && !bTextEditOnlyOneView && pNewWin->GetOutDevType()==OUTDEV_WINDOW)
1814     {
1815         OutlinerView* pOutlView=ImpMakeOutlinerView((Window*)pNewWin,sal_False,NULL);
1816         pTextEditOutliner->InsertView(pOutlView);
1817     }
1818 }
1819 
1820 void SdrObjEditView::DeleteWindowFromPaintView(OutputDevice* pOldWin)
1821 {
1822     SdrGlueEditView::DeleteWindowFromPaintView(pOldWin);
1823 
1824     if(mxTextEditObj.is() && !bTextEditOnlyOneView && pOldWin->GetOutDevType()==OUTDEV_WINDOW)
1825     {
1826         for (sal_uIntPtr i=pTextEditOutliner->GetViewCount(); i>0;) {
1827             i--;
1828             OutlinerView* pOLV=pTextEditOutliner->GetView(i);
1829             if (pOLV && pOLV->GetWindow()==(Window*)pOldWin) {
1830                 delete pTextEditOutliner->RemoveView(i);
1831             }
1832         }
1833     }
1834 }
1835 
1836 sal_Bool SdrObjEditView::IsTextEditInSelectionMode() const
1837 {
1838     return pTextEditOutliner!=NULL && pTextEditOutliner->IsInSelectionMode();
1839 }
1840 
1841 ////////////////////////////////////////////////////////////////////////////////////////////////////
1842 //
1843 //  @@   @@  @@@@   @@@@  @@@@@   @@@@   @@   @@  @@@@  @@@@@  @@@@@
1844 //  @@@ @@@ @@  @@ @@  @@ @@  @@ @@  @@  @@@ @@@ @@  @@ @@  @@ @@
1845 //  @@@@@@@ @@  @@ @@     @@  @@ @@  @@  @@@@@@@ @@  @@ @@  @@ @@
1846 //  @@@@@@@ @@@@@@ @@     @@@@@  @@  @@  @@@@@@@ @@  @@ @@  @@ @@@@
1847 //  @@ @ @@ @@  @@ @@     @@  @@ @@  @@  @@ @ @@ @@  @@ @@  @@ @@
1848 //  @@   @@ @@  @@ @@  @@ @@  @@ @@  @@  @@   @@ @@  @@ @@  @@ @@
1849 //  @@   @@ @@  @@  @@@@  @@  @@  @@@@   @@   @@  @@@@  @@@@@  @@@@@
1850 //
1851 ////////////////////////////////////////////////////////////////////////////////////////////////////
1852 
1853 sal_Bool SdrObjEditView::BegMacroObj(const Point& rPnt, short nTol, SdrObject* pObj, SdrPageView* pPV, Window* pWin)
1854 {
1855     sal_Bool bRet=sal_False;
1856     BrkMacroObj();
1857     if (pObj!=NULL && pPV!=NULL && pWin!=NULL && pObj->HasMacro()) {
1858         nTol=ImpGetHitTolLogic(nTol,NULL);
1859         pMacroObj=pObj;
1860         pMacroPV=pPV;
1861         pMacroWin=pWin;
1862         bMacroDown=sal_False;
1863         nMacroTol=sal_uInt16(nTol);
1864         aMacroDownPos=rPnt;
1865         MovMacroObj(rPnt);
1866     }
1867     return bRet;
1868 }
1869 
1870 void SdrObjEditView::ImpMacroUp(const Point& rUpPos)
1871 {
1872     if (pMacroObj!=NULL && bMacroDown)
1873     {
1874         SdrObjMacroHitRec aHitRec;
1875         aHitRec.aPos=rUpPos;
1876         aHitRec.aDownPos=aMacroDownPos;
1877         aHitRec.nTol=nMacroTol;
1878         aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
1879         aHitRec.pPageView=pMacroPV;
1880         aHitRec.pOut=pMacroWin;
1881         pMacroObj->PaintMacro(*pMacroWin,Rectangle(),aHitRec);
1882         bMacroDown=sal_False;
1883     }
1884 }
1885 
1886 void SdrObjEditView::ImpMacroDown(const Point& rDownPos)
1887 {
1888     if (pMacroObj!=NULL && !bMacroDown)
1889     {
1890         SdrObjMacroHitRec aHitRec;
1891         aHitRec.aPos=rDownPos;
1892         aHitRec.aDownPos=aMacroDownPos;
1893         aHitRec.nTol=nMacroTol;
1894         aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
1895         aHitRec.pPageView=pMacroPV;
1896         aHitRec.bDown=sal_True;
1897         aHitRec.pOut=pMacroWin;
1898         pMacroObj->PaintMacro(*pMacroWin,Rectangle(),aHitRec);
1899         bMacroDown=sal_True;
1900     }
1901 }
1902 
1903 void SdrObjEditView::MovMacroObj(const Point& rPnt)
1904 {
1905     if (pMacroObj!=NULL) {
1906         SdrObjMacroHitRec aHitRec;
1907         aHitRec.aPos=rPnt;
1908         aHitRec.aDownPos=aMacroDownPos;
1909         aHitRec.nTol=nMacroTol;
1910         aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
1911         aHitRec.pPageView=pMacroPV;
1912         aHitRec.bDown=bMacroDown;
1913         aHitRec.pOut=pMacroWin;
1914         sal_Bool bDown=pMacroObj->IsMacroHit(aHitRec);
1915         if (bDown) ImpMacroDown(rPnt);
1916         else ImpMacroUp(rPnt);
1917     }
1918 }
1919 
1920 void SdrObjEditView::BrkMacroObj()
1921 {
1922     if (pMacroObj!=NULL) {
1923         ImpMacroUp(aMacroDownPos);
1924         pMacroObj=NULL;
1925         pMacroPV=NULL;
1926         pMacroWin=NULL;
1927     }
1928 }
1929 
1930 sal_Bool SdrObjEditView::EndMacroObj()
1931 {
1932     if (pMacroObj!=NULL && bMacroDown) {
1933         ImpMacroUp(aMacroDownPos);
1934         SdrObjMacroHitRec aHitRec;
1935         aHitRec.aPos=aMacroDownPos;
1936         aHitRec.aDownPos=aMacroDownPos;
1937         aHitRec.nTol=nMacroTol;
1938         aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
1939         aHitRec.pPageView=pMacroPV;
1940         aHitRec.bDown=sal_True;
1941         aHitRec.pOut=pMacroWin;
1942         bool bRet=pMacroObj->DoMacro(aHitRec);
1943         pMacroObj=NULL;
1944         pMacroPV=NULL;
1945         pMacroWin=NULL;
1946         return bRet;
1947     } else {
1948         BrkMacroObj();
1949         return sal_False;
1950     }
1951 }
1952 
1953 /** fills the given any with a XTextCursor for the current text selection.
1954     Leaves the any untouched if there currently is no text selected */
1955 void SdrObjEditView::getTextSelection( ::com::sun::star::uno::Any& rSelection )
1956 {
1957     if( IsTextEdit() )
1958     {
1959         OutlinerView* pOutlinerView = GetTextEditOutlinerView();
1960         if( pOutlinerView && pOutlinerView->HasSelection() )
1961         {
1962             SdrObject* pObj = GetTextEditObject();
1963 
1964             if( pObj )
1965             {
1966                 ::com::sun::star::uno::Reference< ::com::sun::star::text::XText > xText( pObj->getUnoShape(), ::com::sun::star::uno::UNO_QUERY );
1967                 if( xText.is() )
1968                 {
1969                     SvxUnoTextBase* pRange = SvxUnoTextBase::getImplementation( xText );
1970                     if( pRange )
1971                     {
1972                         rSelection <<= pRange->createTextCursorBySelection( pOutlinerView->GetSelection() );
1973                     }
1974                 }
1975             }
1976         }
1977     }
1978 }
1979 
1980 namespace sdr { namespace table {
1981 extern rtl::Reference< sdr::SelectionController > CreateTableController( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController );
1982 } }
1983 
1984 /* check if we have a single selection and that single object likes
1985     to handle the mouse and keyboard events itself
1986 
1987     @todo: the selection controller should be queried from the
1988     object specific view contact. Currently this method only
1989     works for tables.
1990 */
1991 void SdrObjEditView::MarkListHasChanged()
1992 {
1993     SdrGlueEditView::MarkListHasChanged();
1994 
1995     if( mxSelectionController.is() )
1996     {
1997         mxLastSelectionController = mxSelectionController;
1998         mxSelectionController->onSelectionHasChanged();
1999     }
2000 
2001     mxSelectionController.clear();
2002 
2003     const SdrMarkList& rMarkList=GetMarkedObjectList();
2004     if( rMarkList.GetMarkCount() == 1 )
2005     {
2006         const SdrObject* pObj= rMarkList.GetMark(0)->GetMarkedSdrObj();
2007         // check for table
2008         if( pObj && (pObj->GetObjInventor() == SdrInventor ) && (pObj->GetObjIdentifier() == OBJ_TABLE) )
2009         {
2010             mxSelectionController = sdr::table::CreateTableController( this, pObj, mxLastSelectionController );
2011             if( mxSelectionController.is() )
2012             {
2013                 mxLastSelectionController.clear();
2014                 mxSelectionController->onSelectionHasChanged();
2015             }
2016         }
2017     }
2018 }
2019 
2020 IMPL_LINK( SdrObjEditView, EndPasteOrDropHdl, PasteOrDropInfos*, pInfos )
2021 {
2022     OnEndPasteOrDrop( pInfos );
2023     return 0;
2024 }
2025 
2026 IMPL_LINK( SdrObjEditView, BeginPasteOrDropHdl, PasteOrDropInfos*, pInfos )
2027 {
2028     OnBeginPasteOrDrop( pInfos );
2029     return 0;
2030 }
2031 
2032 void SdrObjEditView::OnBeginPasteOrDrop( PasteOrDropInfos* )
2033 {
2034     // applications can derive from these virtual methods to do something before a drop or paste operation
2035 }
2036 
2037 void SdrObjEditView::OnEndPasteOrDrop( PasteOrDropInfos* )
2038 {
2039     // applications can derive from these virtual methods to do something before a drop or paste operation
2040 }
2041 
2042 sal_uInt16 SdrObjEditView::GetSelectionLevel() const
2043 {
2044     sal_uInt16 nLevel = 0xFFFF;
2045     if( IsTextEdit() )
2046     {
2047         DBG_ASSERT(pTextEditOutlinerView!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
2048         DBG_ASSERT(pTextEditOutliner!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
2049         if( pTextEditOutlinerView )
2050         {
2051             //start and end position
2052             ESelection aSelect = pTextEditOutlinerView->GetSelection();
2053             sal_uInt16 nStartPara = ::std::min( aSelect.nStartPara, aSelect.nEndPara );
2054             sal_uInt16 nEndPara = ::std::max( aSelect.nStartPara, aSelect.nEndPara );
2055             //get level from each paragraph
2056             nLevel = 0;
2057             for( sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++ )
2058             {
2059                 sal_uInt16 nParaDepth = 1 << pTextEditOutliner->GetDepth( nPara );
2060                 if( !(nLevel & nParaDepth) )
2061                     nLevel += nParaDepth;
2062             }
2063             //reduce one level for Outliner Object
2064             //if( nLevel > 0 && GetTextEditObject()->GetObjIdentifier() == OBJ_OUTLINETEXT )
2065             //  nLevel = nLevel >> 1;
2066             //no bullet paragraph selected
2067             if( nLevel == 0)
2068                 nLevel = 0xFFFF;
2069         }
2070     }
2071     return nLevel;
2072 }
2073 
2074 bool SdrObjEditView::SupportsFormatPaintbrush( sal_uInt32 nObjectInventor, sal_uInt16 nObjectIdentifier ) const
2075 {
2076     if( nObjectInventor != SdrInventor && nObjectInventor != E3dInventor )
2077         return false;
2078     switch(nObjectIdentifier)
2079     {
2080         case OBJ_NONE:
2081         case OBJ_GRUP:
2082             return false;
2083         case OBJ_LINE:
2084         case OBJ_RECT:
2085         case OBJ_CIRC:
2086         case OBJ_SECT:
2087         case OBJ_CARC:
2088         case OBJ_CCUT:
2089         case OBJ_POLY:
2090         case OBJ_PLIN:
2091         case OBJ_PATHLINE:
2092         case OBJ_PATHFILL:
2093         case OBJ_FREELINE:
2094         case OBJ_FREEFILL:
2095         case OBJ_SPLNLINE:
2096         case OBJ_SPLNFILL:
2097         case OBJ_TEXT:
2098         case OBJ_TEXTEXT:
2099         case OBJ_TITLETEXT:
2100         case OBJ_OUTLINETEXT:
2101         case OBJ_GRAF:
2102         case OBJ_OLE2:
2103         case OBJ_TABLE:
2104             return true;
2105         case OBJ_EDGE:
2106         case OBJ_CAPTION:
2107             return false;
2108         case OBJ_PATHPOLY:
2109         case OBJ_PATHPLIN:
2110             return true;
2111         case OBJ_PAGE:
2112         case OBJ_MEASURE:
2113         case OBJ_DUMMY:
2114         case OBJ_FRAME:
2115         case OBJ_UNO:
2116             return false;
2117         case OBJ_CUSTOMSHAPE:
2118             return true;
2119         default:
2120             return false;
2121     }
2122 }
2123 
2124 static const sal_uInt16* GetFormatRangeImpl( bool bTextOnly )
2125 {
2126     static const sal_uInt16 gRanges[] = {
2127         SDRATTR_SHADOW_FIRST, SDRATTR_SHADOW_LAST,
2128         SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST,
2129         SDRATTR_TABLE_FIRST, SDRATTR_TABLE_LAST,
2130         XATTR_LINE_FIRST, XATTR_LINE_LAST,
2131         XATTR_FILL_FIRST, XATTRSET_FILL,
2132         EE_PARA_START, EE_PARA_END,
2133         EE_CHAR_START, EE_CHAR_END,
2134         0,0
2135     };
2136     return &gRanges[ bTextOnly ? 10 : 0];
2137 }
2138 
2139 bool SdrObjEditView::TakeFormatPaintBrush( boost::shared_ptr< SfxItemSet >& rFormatSet  )
2140 {
2141     if( mxSelectionController.is() && mxSelectionController->TakeFormatPaintBrush(rFormatSet) )
2142         return true;
2143 
2144     const SdrMarkList& rMarkList = GetMarkedObjectList();
2145     if( rMarkList.GetMarkCount() >= 1 )
2146     {
2147         OutlinerView* pOLV = GetTextEditOutlinerView();
2148 
2149         rFormatSet.reset( new SfxItemSet( GetModel()->GetItemPool(), GetFormatRangeImpl( pOLV != NULL ) ) );
2150         if( pOLV )
2151         {
2152             rFormatSet->Put( pOLV->GetAttribs() );
2153         }
2154         else
2155         {
2156             const sal_Bool bOnlyHardAttr = sal_False;
2157             rFormatSet->Put( GetAttrFromMarked(bOnlyHardAttr) );
2158         }
2159         return true;
2160     }
2161 
2162     return false;
2163 }
2164 
2165 static SfxItemSet CreatePaintSet( const sal_uInt16 *pRanges, SfxItemPool& rPool, const SfxItemSet& rSourceSet, const SfxItemSet& rTargetSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
2166 {
2167     SfxItemSet aPaintSet( rPool, pRanges );
2168 
2169     while( *pRanges )
2170     {
2171         sal_uInt16 nWhich = *pRanges++;
2172         const sal_uInt16 nLastWhich = *pRanges++;
2173 
2174         if( bNoCharacterFormats && (nWhich == EE_CHAR_START) )
2175             continue;
2176 
2177         if( bNoParagraphFormats && (nWhich == EE_PARA_START ) )
2178             continue;
2179 
2180         for( ; nWhich < nLastWhich; nWhich++ )
2181         {
2182             const SfxPoolItem* pSourceItem = rSourceSet.GetItem( nWhich );
2183             const SfxPoolItem* pTargetItem = rTargetSet.GetItem( nWhich );
2184 
2185             if( (pSourceItem && !pTargetItem) || (pSourceItem && pTargetItem && !((*pSourceItem) == (*pTargetItem)) ) )
2186             {
2187                 aPaintSet.Put( *pSourceItem );
2188             }
2189         }
2190     }
2191     return aPaintSet;
2192 }
2193 
2194 void SdrObjEditView::ApplyFormatPaintBrushToText( SfxItemSet& rFormatSet, SdrTextObj& rTextObj, SdrText* pText, bool bNoCharacterFormats, bool bNoParagraphFormats )
2195 {
2196     OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : 0;
2197     if(pParaObj)
2198     {
2199         SdrOutliner& rOutliner = rTextObj.ImpGetDrawOutliner();
2200         rOutliner.SetText(*pParaObj);
2201 
2202         sal_uInt32 nParaCount(rOutliner.GetParagraphCount());
2203 
2204         if(nParaCount)
2205         {
2206             for(sal_uInt16 nPara = 0; nPara < nParaCount; nPara++)
2207             {
2208                 if( !bNoCharacterFormats )
2209                     rOutliner.QuickRemoveCharAttribs( nPara, /* remove all */0 );
2210 
2211                 SfxItemSet aSet(rOutliner.GetParaAttribs(nPara));
2212                 aSet.Put(CreatePaintSet( GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet, bNoCharacterFormats, bNoParagraphFormats ) );
2213                 rOutliner.SetParaAttribs(nPara, aSet);
2214             }
2215 
2216             OutlinerParaObject* pTemp = rOutliner.CreateParaObject(0, (sal_uInt16)nParaCount);
2217             rOutliner.Clear();
2218 
2219             rTextObj.NbcSetOutlinerParaObjectForText(pTemp,pText);
2220         }
2221     }
2222 }
2223 
2224 void SdrObjEditView::ApplyFormatPaintBrush( SfxItemSet& rFormatSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
2225 {
2226     if( !mxSelectionController.is() || !mxSelectionController->ApplyFormatPaintBrush( rFormatSet, bNoCharacterFormats, bNoParagraphFormats ) )
2227     {
2228         const SdrMarkList& rMarkList = GetMarkedObjectList();
2229         SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2230         OutlinerView* pOLV = GetTextEditOutlinerView();
2231 
2232         const SfxItemSet& rShapeSet = pObj->GetMergedItemSet();
2233 
2234         if( !pOLV )
2235         {
2236             // if not in text edit mode (aka the user selected text or clicked on a word)
2237             // apply formating attributes to selected shape
2238             // All formating items (see ranges above) that are unequal in selected shape and
2239             // the format paintbrush are hard set on the selected shape.
2240 
2241             const sal_uInt16* pRanges = rFormatSet.GetRanges();
2242             bool bTextOnly = true;
2243 
2244             while( *pRanges )
2245             {
2246                 if( (*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START) )
2247                 {
2248                     bTextOnly = false;
2249                     break;
2250                 }
2251                 pRanges += 2;
2252             }
2253 
2254             if( !bTextOnly )
2255             {
2256                 SfxItemSet aPaintSet( CreatePaintSet( GetFormatRangeImpl(false), *rShapeSet.GetPool(), rFormatSet, rShapeSet, bNoCharacterFormats, bNoParagraphFormats ) );
2257                 const sal_Bool bReplaceAll = sal_False;
2258                 SetAttrToMarked(aPaintSet, bReplaceAll);
2259             }
2260 
2261             // now apply character and paragraph formating to text, if the shape has any
2262             SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(pObj);
2263             if( pTextObj )
2264             {
2265                 sal_Int32 nText = pTextObj->getTextCount();
2266 
2267                 while( --nText >= 0 )
2268                 {
2269                     SdrText* pText = pTextObj->getText( nText );
2270                     ApplyFormatPaintBrushToText( rFormatSet, *pTextObj, pText, bNoCharacterFormats, bNoParagraphFormats );
2271                 }
2272             }
2273         }
2274         else
2275         {
2276             ::Outliner* pOutliner = pOLV->GetOutliner();
2277             if( pOutliner )
2278             {
2279                 const EditEngine& rEditEngine = pOutliner->GetEditEngine();
2280 
2281                 ESelection aSel( pOLV->GetSelection() );
2282                 if( !aSel.HasRange() )
2283                     pOLV->SetSelection( rEditEngine.GetWord( aSel, com::sun::star::i18n::WordType::DICTIONARY_WORD ) );
2284 
2285                 const sal_Bool bRemoveParaAttribs = !bNoParagraphFormats;
2286                 pOLV->RemoveAttribsKeepLanguages( bRemoveParaAttribs );
2287                 SfxItemSet aSet( pOLV->GetAttribs() );
2288                 SfxItemSet aPaintSet( CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet, bNoCharacterFormats, bNoParagraphFormats ) );
2289                 pOLV->SetAttribs( aPaintSet );
2290             }
2291         }
2292     }
2293 }
2294