xref: /trunk/main/svx/source/svdraw/svdedxv.cxx (revision 766ce4d0)
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 sal_uInt16 SdrObjEditView::GetSelectionLevel() const
2056 {
2057 	sal_uInt16 nLevel = 0xFFFF;
2058     if( IsTextEdit() )
2059 	{
2060         DBG_ASSERT(pTextEditOutlinerView!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
2061         DBG_ASSERT(pTextEditOutliner!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
2062 		if( pTextEditOutlinerView )
2063 		{
2064 			//start and end position
2065 			ESelection aSelect = pTextEditOutlinerView->GetSelection();
2066 			sal_uInt16 nStartPara = ::std::min( aSelect.nStartPara, aSelect.nEndPara );
2067 			sal_uInt16 nEndPara = ::std::max( aSelect.nStartPara, aSelect.nEndPara );
2068 			//get level from each paragraph
2069 			nLevel = 0;
2070 			for( sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++ )
2071 			{
2072 				sal_uInt16 nParaDepth = 1 << pTextEditOutliner->GetDepth( nPara );
2073 				if( !(nLevel & nParaDepth) )
2074 					nLevel += nParaDepth;
2075 			}
2076 			//reduce one level for Outliner Object
2077 			//if( nLevel > 0 && GetTextEditObject()->GetObjIdentifier() == OBJ_OUTLINETEXT )
2078 			//	nLevel = nLevel >> 1;
2079 			//no bullet paragraph selected
2080 			if( nLevel == 0)
2081 				nLevel = 0xFFFF;
2082 		}
2083 	}
2084 	return nLevel;
2085 }
2086 
2087 bool SdrObjEditView::SupportsFormatPaintbrush( sal_uInt32 nObjectInventor, sal_uInt16 nObjectIdentifier ) const
2088 {
2089     if( nObjectInventor != SdrInventor && nObjectInventor != E3dInventor )
2090         return false;
2091     switch(nObjectIdentifier)
2092     {
2093         case OBJ_NONE:
2094         case OBJ_GRUP:
2095             return false;
2096         case OBJ_LINE:
2097         case OBJ_RECT:
2098         case OBJ_CIRC:
2099         case OBJ_SECT:
2100         case OBJ_CARC:
2101         case OBJ_CCUT:
2102         case OBJ_POLY:
2103         case OBJ_PLIN:
2104         case OBJ_PATHLINE:
2105         case OBJ_PATHFILL:
2106         case OBJ_FREELINE:
2107         case OBJ_FREEFILL:
2108         case OBJ_SPLNLINE:
2109         case OBJ_SPLNFILL:
2110         case OBJ_TEXT:
2111         case OBJ_TEXTEXT:
2112         case OBJ_TITLETEXT:
2113         case OBJ_OUTLINETEXT:
2114         case OBJ_GRAF:
2115         case OBJ_OLE2:
2116 		case OBJ_TABLE:
2117             return true;
2118         case OBJ_EDGE:
2119         case OBJ_CAPTION:
2120             return false;
2121         case OBJ_PATHPOLY:
2122         case OBJ_PATHPLIN:
2123             return true;
2124         case OBJ_PAGE:
2125         case OBJ_MEASURE:
2126         case OBJ_DUMMY:
2127         case OBJ_FRAME:
2128         case OBJ_UNO:
2129             return false;
2130         case OBJ_CUSTOMSHAPE:
2131             return true;
2132         default:
2133             return false;
2134     }
2135 }
2136 
2137 static const sal_uInt16* GetFormatRangeImpl( bool bTextOnly )
2138 {
2139     static const sal_uInt16 gRanges[] = {
2140         SDRATTR_SHADOW_FIRST, SDRATTR_SHADOW_LAST,
2141         SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST,
2142         SDRATTR_TABLE_FIRST, SDRATTR_TABLE_LAST,
2143         XATTR_LINE_FIRST, XATTR_LINE_LAST,
2144         XATTR_FILL_FIRST, XATTRSET_FILL,
2145         EE_PARA_START, EE_PARA_END,
2146         EE_CHAR_START, EE_CHAR_END,
2147         0,0
2148     };
2149     return &gRanges[ bTextOnly ? 10 : 0];
2150 }
2151 
2152 bool SdrObjEditView::TakeFormatPaintBrush( boost::shared_ptr< SfxItemSet >& rFormatSet  )
2153 {
2154     if( mxSelectionController.is() && mxSelectionController->TakeFormatPaintBrush(rFormatSet) )
2155         return true;
2156 
2157 	const SdrMarkList& rMarkList = GetMarkedObjectList();
2158 	if( rMarkList.GetMarkCount() >= 1 )
2159 	{
2160 	    OutlinerView* pOLV = GetTextEditOutlinerView();
2161 
2162 	    rFormatSet.reset( new SfxItemSet( GetModel()->GetItemPool(), GetFormatRangeImpl( pOLV != NULL ) ) );
2163 	    if( pOLV )
2164 	    {
2165             rFormatSet->Put( pOLV->GetAttribs() );
2166 	    }
2167 	    else
2168 	    {
2169 		    const sal_Bool bOnlyHardAttr = sal_False;
2170 		    rFormatSet->Put( GetAttrFromMarked(bOnlyHardAttr) );
2171 		}
2172 		return true;
2173 	}
2174 
2175     return false;
2176 }
2177 
2178 static SfxItemSet CreatePaintSet( const sal_uInt16 *pRanges, SfxItemPool& rPool, const SfxItemSet& rSourceSet, const SfxItemSet& rTargetSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
2179 {
2180 	SfxItemSet aPaintSet( rPool, pRanges );
2181 
2182 	while( *pRanges )
2183 	{
2184 		sal_uInt16 nWhich = *pRanges++;
2185 		const sal_uInt16 nLastWhich = *pRanges++;
2186 
2187 		if( bNoCharacterFormats && (nWhich == EE_CHAR_START) )
2188 			continue;
2189 
2190 		if( bNoParagraphFormats && (nWhich == EE_PARA_START ) )
2191 			continue;
2192 
2193 		for( ; nWhich < nLastWhich; nWhich++ )
2194 		{
2195 			const SfxPoolItem* pSourceItem = rSourceSet.GetItem( nWhich );
2196 			const SfxPoolItem* pTargetItem = rTargetSet.GetItem( nWhich );
2197 
2198 			if( (pSourceItem && !pTargetItem) || (pSourceItem && pTargetItem && !((*pSourceItem) == (*pTargetItem)) ) )
2199 			{
2200 				aPaintSet.Put( *pSourceItem );
2201 			}
2202 		}
2203 	}
2204 	return aPaintSet;
2205 }
2206 
2207 void SdrObjEditView::ApplyFormatPaintBrushToText( SfxItemSet& rFormatSet, SdrTextObj& rTextObj, SdrText* pText, bool bNoCharacterFormats, bool bNoParagraphFormats )
2208 {
2209     OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : 0;
2210     if(pParaObj)
2211     {
2212 	    SdrOutliner& rOutliner = rTextObj.ImpGetDrawOutliner();
2213 	    rOutliner.SetText(*pParaObj);
2214 
2215 	    sal_uInt32 nParaCount(rOutliner.GetParagraphCount());
2216 
2217 	    if(nParaCount)
2218 	    {
2219 		    for(sal_uInt16 nPara = 0; nPara < nParaCount; nPara++)
2220 		    {
2221 			    if( !bNoCharacterFormats )
2222 				    rOutliner.QuickRemoveCharAttribs( nPara, /* remove all */0 );
2223 
2224 			    SfxItemSet aSet(rOutliner.GetParaAttribs(nPara));
2225 			    aSet.Put(CreatePaintSet( GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet, bNoCharacterFormats, bNoParagraphFormats ) );
2226 			    rOutliner.SetParaAttribs(nPara, aSet);
2227 		    }
2228 
2229 		    OutlinerParaObject* pTemp = rOutliner.CreateParaObject(0, (sal_uInt16)nParaCount);
2230 		    rOutliner.Clear();
2231 
2232 		    rTextObj.NbcSetOutlinerParaObjectForText(pTemp,pText);
2233 	    }
2234     }
2235 }
2236 
2237 void SdrObjEditView::ApplyFormatPaintBrush( SfxItemSet& rFormatSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
2238 {
2239     if( !mxSelectionController.is() || !mxSelectionController->ApplyFormatPaintBrush( rFormatSet, bNoCharacterFormats, bNoParagraphFormats ) )
2240     {
2241         const SdrMarkList& rMarkList = GetMarkedObjectList();
2242         SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2243 	    OutlinerView* pOLV = GetTextEditOutlinerView();
2244 
2245         const SfxItemSet& rShapeSet = pObj->GetMergedItemSet();
2246 
2247 	    if( !pOLV )
2248 	    {
2249 		    // if not in text edit mode (aka the user selected text or clicked on a word)
2250 		    // apply formating attributes to selected shape
2251 		    // All formating items (see ranges above) that are unequal in selected shape and
2252 		    // the format paintbrush are hard set on the selected shape.
2253 
2254             const sal_uInt16* pRanges = rFormatSet.GetRanges();
2255             bool bTextOnly = true;
2256 
2257             while( *pRanges )
2258             {
2259                 if( (*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START) )
2260                 {
2261                     bTextOnly = false;
2262                     break;
2263                 }
2264                 pRanges += 2;
2265             }
2266 
2267 		    if( !bTextOnly )
2268 		    {
2269 			    SfxItemSet aPaintSet( CreatePaintSet( GetFormatRangeImpl(false), *rShapeSet.GetPool(), rFormatSet, rShapeSet, bNoCharacterFormats, bNoParagraphFormats ) );
2270 			    const sal_Bool bReplaceAll = sal_False;
2271 			    SetAttrToMarked(aPaintSet, bReplaceAll);
2272 		    }
2273 
2274 		    // now apply character and paragraph formating to text, if the shape has any
2275 		    SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(pObj);
2276 		    if( pTextObj )
2277 		    {
2278 			    sal_Int32 nText = pTextObj->getTextCount();
2279 
2280 			    while( --nText >= 0 )
2281 			    {
2282                     SdrText* pText = pTextObj->getText( nText );
2283                     ApplyFormatPaintBrushToText( rFormatSet, *pTextObj, pText, bNoCharacterFormats, bNoParagraphFormats );
2284 			    }
2285 		    }
2286 	    }
2287 	    else
2288 	    {
2289 		    ::Outliner* pOutliner = pOLV->GetOutliner();
2290 		    if( pOutliner )
2291 		    {
2292 			    const EditEngine& rEditEngine = pOutliner->GetEditEngine();
2293 
2294 			    ESelection aSel( pOLV->GetSelection() );
2295 			    if( !aSel.HasRange() )
2296 				    pOLV->SetSelection( rEditEngine.GetWord( aSel, com::sun::star::i18n::WordType::DICTIONARY_WORD ) );
2297 
2298 			    const sal_Bool bRemoveParaAttribs = !bNoParagraphFormats;
2299 			    pOLV->RemoveAttribsKeepLanguages( bRemoveParaAttribs );
2300 			    SfxItemSet aSet( pOLV->GetAttribs() );
2301 			    SfxItemSet aPaintSet( CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet, bNoCharacterFormats, bNoParagraphFormats ) );
2302 			    pOLV->SetAttribs( aPaintSet );
2303 		    }
2304 	    }
2305     }
2306 }
2307