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