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