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