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