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