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 waehrend 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 happened 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==(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==(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_uInt32 nStartPara = ::std::min( aSelect.nStartPara, aSelect.nEndPara );
2050 sal_uInt32 nEndPara = ::std::max( aSelect.nStartPara, aSelect.nEndPara );
2051 //get level from each paragraph
2052 nLevel = 0;
2053 for( sal_uInt32 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_uInt32 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, 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 formatting attributes to selected shape
2234 // All formatting 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 formatting 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