bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / svdraw / svdedxv.cxx
blob6134278eddb85496ec36e3d89a61764e2eca0935
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <com/sun/star/i18n/WordType.hpp>
23 #include <svtools/accessibilityoptions.hxx>
25 #include <svx/svdedxv.hxx>
26 #include <svl/solar.hrc>
28 #include <svl/itemiter.hxx>
29 #include <vcl/msgbox.hxx>
30 #include <vcl/hatch.hxx>
31 #include <svl/whiter.hxx>
32 #include <svl/style.hxx>
33 #include <editeng/editstat.hxx>
34 #include <vcl/cursor.hxx>
35 #include <editeng/unotext.hxx>
37 #include <editeng/editdata.hxx>
38 #include <editeng/editeng.hxx>
39 #include <editeng/editobj.hxx>
40 #include <editeng/outlobj.hxx>
41 #include <editeng/scripttypeitem.hxx>
42 #include <svx/svdoutl.hxx>
43 #include <svx/sdtfchim.hxx>
44 #include <svx/svdotext.hxx>
45 #include <svx/svdundo.hxx>
46 #include "svx/svditer.hxx"
47 #include "svx/svdpagv.hxx"
48 #include "svx/svdpage.hxx"
49 #include "svx/svdetc.hxx" // for GetDraftFillColor
50 #include "svx/svdotable.hxx"
51 #include <svx/selectioncontroller.hxx>
52 #ifdef DBG_UTIL
53 #include <svdibrow.hxx>
54 #endif
56 #include <svx/svddrgv.hxx> // for SetSolidDragging()
57 #include "svx/svdstr.hrc" // names taken from the resource
58 #include "svx/svdglob.hxx" // StringCache
59 #include "svx/globl3d.hxx"
60 #include <editeng/outliner.hxx>
61 #include <editeng/adjustitem.hxx>
63 #include <svtools/colorcfg.hxx>
64 #include <vcl/svapp.hxx>
65 #include <svx/sdrpaintwindow.hxx>
67 ////////////////////////////////////////////////////////////////////////////////////////////////////
69 void SdrObjEditView::ImpClearVars()
71 bQuickTextEditMode=sal_True;
72 bMacroMode=sal_True;
73 pTextEditOutliner=NULL;
74 pTextEditOutlinerView=NULL;
75 pTextEditPV=NULL;
76 pTextEditWin=NULL;
77 pTextEditCursorMerker=NULL;
78 pEditPara=NULL;
79 bTextEditNewObj=sal_False;
80 bMacroDown=sal_False;
81 pMacroObj=NULL;
82 pMacroPV=NULL;
83 pMacroWin=NULL;
84 nMacroTol=0;
85 bTextEditDontDelete=sal_False;
86 bTextEditOnlyOneView=sal_False;
89 SdrObjEditView::SdrObjEditView(SdrModel* pModel1, OutputDevice* pOut):
90 SdrGlueEditView(pModel1,pOut)
92 ImpClearVars();
95 SdrObjEditView::~SdrObjEditView()
97 pTextEditWin = NULL; // so there's no ShowCursor in SdrEndTextEdit
98 if (IsTextEdit()) SdrEndTextEdit();
99 delete pTextEditOutliner;
102 ////////////////////////////////////////////////////////////////////////////////////////////////////
104 sal_Bool SdrObjEditView::IsAction() const
106 return IsMacroObj() || SdrGlueEditView::IsAction();
109 void SdrObjEditView::MovAction(const Point& rPnt)
111 if (IsMacroObj()) MovMacroObj(rPnt);
112 SdrGlueEditView::MovAction(rPnt);
115 void SdrObjEditView::EndAction()
117 if (IsMacroObj()) EndMacroObj();
118 SdrGlueEditView::EndAction();
121 void SdrObjEditView::BckAction()
123 BrkMacroObj();
124 SdrGlueEditView::BckAction();
127 void SdrObjEditView::BrkAction()
129 BrkMacroObj();
130 SdrGlueEditView::BrkAction();
133 void SdrObjEditView::TakeActionRect(Rectangle& rRect) const
135 if (IsMacroObj()) {
136 rRect=pMacroObj->GetCurrentBoundRect();
137 } else {
138 SdrGlueEditView::TakeActionRect(rRect);
142 void SdrObjEditView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
144 SdrGlueEditView::Notify(rBC,rHint);
145 // change of printer while editing
146 SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint);
147 if (pSdrHint!=NULL && pTextEditOutliner!=NULL) {
148 SdrHintKind eKind=pSdrHint->GetKind();
149 if (eKind==HINT_REFDEVICECHG) {
150 pTextEditOutliner->SetRefDevice(pMod->GetRefDevice());
152 if (eKind==HINT_DEFAULTTABCHG) {
153 pTextEditOutliner->SetDefTab(pMod->GetDefaultTabulator());
155 if (eKind==HINT_DEFFONTHGTCHG) {
156 // ...
158 if (eKind==HINT_MODELSAVED) {
159 pTextEditOutliner->ClearModifyFlag();
164 void SdrObjEditView::ModelHasChanged()
166 SdrGlueEditView::ModelHasChanged();
167 if (mxTextEditObj.is() && !mxTextEditObj->IsInserted()) SdrEndTextEdit(); // object deleted
168 // TextEditObj changed?
169 if (IsTextEdit()) {
170 SdrTextObj* pTextObj=dynamic_cast<SdrTextObj*>( mxTextEditObj.get() );
171 if (pTextObj!=NULL) {
172 sal_uIntPtr nOutlViewAnz=pTextEditOutliner->GetViewCount();
173 bool bAreaChg=false;
174 bool bAnchorChg=false;
175 bool bColorChg=false;
176 bool bContourFrame=pTextObj->IsContourTextFrame();
177 EVAnchorMode eNewAnchor(ANCHOR_VCENTER_HCENTER);
178 Rectangle aOldArea(aMinTextEditArea);
179 aOldArea.Union(aTextEditArea);
180 Color aNewColor;
181 { // check area
182 Size aPaperMin1;
183 Size aPaperMax1;
184 Rectangle aEditArea1;
185 Rectangle aMinArea1;
186 pTextObj->TakeTextEditArea(&aPaperMin1,&aPaperMax1,&aEditArea1,&aMinArea1);
188 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 aEditArea1 += pTextObj->GetGridOffset();
193 aMinArea1 += pTextObj->GetGridOffset();
194 aEditArea1.Move(aPvOfs.X(),aPvOfs.Y());
195 aMinArea1.Move(aPvOfs.X(),aPvOfs.Y());
196 Rectangle aNewArea(aMinArea1);
197 aNewArea.Union(aEditArea1);
199 if (aNewArea!=aOldArea || aEditArea1!=aTextEditArea || aMinArea1!=aMinTextEditArea ||
200 pTextEditOutliner->GetMinAutoPaperSize()!=aPaperMin1 || pTextEditOutliner->GetMaxAutoPaperSize()!=aPaperMax1) {
201 aTextEditArea=aEditArea1;
202 aMinTextEditArea=aMinArea1;
203 pTextEditOutliner->SetUpdateMode(sal_False);
204 pTextEditOutliner->SetMinAutoPaperSize(aPaperMin1);
205 pTextEditOutliner->SetMaxAutoPaperSize(aPaperMax1);
206 pTextEditOutliner->SetPaperSize(Size(0,0)); // re-format Outliner
207 if (!bContourFrame) {
208 pTextEditOutliner->ClearPolygon();
209 sal_uIntPtr nStat=pTextEditOutliner->GetControlWord();
210 nStat|=EE_CNTRL_AUTOPAGESIZE;
211 pTextEditOutliner->SetControlWord(nStat);
212 } else {
213 sal_uIntPtr nStat=pTextEditOutliner->GetControlWord();
214 nStat&=~EE_CNTRL_AUTOPAGESIZE;
215 pTextEditOutliner->SetControlWord(nStat);
216 Rectangle aAnchorRect;
217 pTextObj->TakeTextAnchorRect(aAnchorRect);
218 pTextObj->ImpSetContourPolygon(*pTextEditOutliner,aAnchorRect, sal_True);
220 for (sal_uIntPtr nOV=0; nOV<nOutlViewAnz; nOV++) {
221 OutlinerView* pOLV=pTextEditOutliner->GetView(nOV);
222 sal_uIntPtr nStat0=pOLV->GetControlWord();
223 sal_uIntPtr nStat=nStat0;
224 // AutoViewSize only if not ContourFrame.
225 if (!bContourFrame) nStat|=EV_CNTRL_AUTOSIZE;
226 else nStat&=~EV_CNTRL_AUTOSIZE;
227 if (nStat!=nStat0) pOLV->SetControlWord(nStat);
229 pTextEditOutliner->SetUpdateMode(sal_True);
230 bAreaChg=true;
233 if (pTextEditOutlinerView!=NULL) { // check fill and anchor
234 EVAnchorMode eOldAnchor=pTextEditOutlinerView->GetAnchorMode();
235 eNewAnchor=(EVAnchorMode)pTextObj->GetOutlinerViewAnchorMode();
236 bAnchorChg=eOldAnchor!=eNewAnchor;
237 Color aOldColor(pTextEditOutlinerView->GetBackgroundColor());
238 aNewColor = GetTextEditBackgroundColor(*this);
239 bColorChg=aOldColor!=aNewColor;
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 if (bContourFrame || bAreaChg || bAnchorChg || bColorChg)
258 for (sal_uIntPtr nOV=0; nOV<nOutlViewAnz; nOV++)
260 OutlinerView* pOLV=pTextEditOutliner->GetView(nOV);
261 { // invalidate old OutlinerView area
262 Window* pWin=pOLV->GetWindow();
263 Rectangle aTmpRect(aOldArea);
264 sal_uInt16 nPixSiz=pOLV->GetInvalidateMore()+1;
265 Size aMore(pWin->PixelToLogic(Size(nPixSiz,nPixSiz)));
266 aTmpRect.Left()-=aMore.Width();
267 aTmpRect.Right()+=aMore.Width();
268 aTmpRect.Top()-=aMore.Height();
269 aTmpRect.Bottom()+=aMore.Height();
270 InvalidateOneWin(*pWin,aTmpRect);
272 if (bAnchorChg)
273 pOLV->SetAnchorMode(eNewAnchor);
274 if (bColorChg)
275 pOLV->SetBackgroundColor( aNewColor );
277 pOLV->SetOutputArea(aTextEditArea); // because otherwise, we're not re-anchoring correctly
278 ImpInvalidateOutlinerView(*pOLV);
280 pTextEditOutlinerView->ShowCursor();
283 ImpMakeTextCursorAreaVisible();
287 ////////////////////////////////////////////////////////////////////////////////////////////////////
288 // TextEdit
289 ////////////////////////////////////////////////////////////////////////////////////////////////////
291 void SdrObjEditView::TextEditDrawing(SdrPaintWindow& rPaintWindow) const
293 // draw old text edit stuff
294 if(IsTextEdit())
296 const SdrOutliner* pActiveOutliner = GetTextEditOutliner();
298 if(pActiveOutliner)
300 const sal_uInt32 nViewAnz(pActiveOutliner->GetViewCount());
302 if(nViewAnz)
304 const Region& rRedrawRegion = rPaintWindow.GetRedrawRegion();
305 const Rectangle aCheckRect(rRedrawRegion.GetBoundRect());
307 for(sal_uInt32 i(0); i < nViewAnz; i++)
309 OutlinerView* pOLV = pActiveOutliner->GetView(i);
311 if(pOLV->GetWindow() == &rPaintWindow.GetOutputDevice())
313 ImpPaintOutlinerView(*pOLV, aCheckRect, rPaintWindow.GetTargetOutputDevice());
314 return;
322 void SdrObjEditView::ImpPaintOutlinerView(OutlinerView& rOutlView, const Rectangle& rRect, OutputDevice& rTargetDevice) const
324 const SdrTextObj* pText = PTR_CAST(SdrTextObj,GetTextEditObject());
325 bool bTextFrame(pText && pText->IsTextFrame());
326 bool bFitToSize(0 != (pTextEditOutliner->GetControlWord() & EE_CNTRL_STRETCHING));
327 bool bModifyMerk(pTextEditOutliner->IsModified()); // #43095#
328 Rectangle aBlankRect(rOutlView.GetOutputArea());
329 aBlankRect.Union(aMinTextEditArea);
330 Rectangle aPixRect(rTargetDevice.LogicToPixel(aBlankRect));
331 aBlankRect.Intersection(rRect);
332 rOutlView.GetOutliner()->SetUpdateMode(sal_True); // Bugfix #22596#
333 rOutlView.Paint(aBlankRect, &rTargetDevice);
335 if(!bModifyMerk)
337 // #43095#
338 pTextEditOutliner->ClearModifyFlag();
341 if(bTextFrame && !bFitToSize)
343 aPixRect.Left()--;
344 aPixRect.Top()--;
345 aPixRect.Right()++;
346 aPixRect.Bottom()++;
347 sal_uInt16 nPixSiz(rOutlView.GetInvalidateMore() - 1);
350 // xPixRect Begrenzen, wegen Treiberproblem bei zu weit hinausragenden Pixelkoordinaten
351 Size aMaxXY(rTargetDevice.GetOutputSizePixel());
352 long a(2 * nPixSiz);
353 long nMaxX(aMaxXY.Width() + a);
354 long nMaxY(aMaxXY.Height() + a);
356 if (aPixRect.Left ()<-a) aPixRect.Left()=-a;
357 if (aPixRect.Top ()<-a) aPixRect.Top ()=-a;
358 if (aPixRect.Right ()>nMaxX) aPixRect.Right ()=nMaxX;
359 if (aPixRect.Bottom()>nMaxY) aPixRect.Bottom()=nMaxY;
362 Rectangle aOuterPix(aPixRect);
363 aOuterPix.Left()-=nPixSiz;
364 aOuterPix.Top()-=nPixSiz;
365 aOuterPix.Right()+=nPixSiz;
366 aOuterPix.Bottom()+=nPixSiz;
368 bool bMerk(rTargetDevice.IsMapModeEnabled());
369 rTargetDevice.EnableMapMode(sal_False);
370 PolyPolygon aPolyPoly( 2 );
372 svtools::ColorConfig aColorConfig;
373 Color aHatchCol( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
374 const Hatch aHatch( HATCH_SINGLE, aHatchCol, 3, 450 );
376 aPolyPoly.Insert( aOuterPix );
377 aPolyPoly.Insert( aPixRect );
378 rTargetDevice.DrawHatch( aPolyPoly, aHatch );
380 rTargetDevice.EnableMapMode(bMerk);
383 rOutlView.ShowCursor();
386 void SdrObjEditView::ImpInvalidateOutlinerView(OutlinerView& rOutlView) const
388 Window* pWin = rOutlView.GetWindow();
390 if(pWin)
392 const SdrTextObj* pText = PTR_CAST(SdrTextObj,GetTextEditObject());
393 bool bTextFrame(pText && pText->IsTextFrame());
394 bool bFitToSize(pText && pText->IsFitToSize());
396 if(bTextFrame && !bFitToSize)
398 Rectangle aBlankRect(rOutlView.GetOutputArea());
399 aBlankRect.Union(aMinTextEditArea);
400 Rectangle aPixRect(pWin->LogicToPixel(aBlankRect));
401 sal_uInt16 nPixSiz(rOutlView.GetInvalidateMore() - 1);
403 aPixRect.Left()--;
404 aPixRect.Top()--;
405 aPixRect.Right()++;
406 aPixRect.Bottom()++;
409 // limit xPixRect because of driver problems when pixel coordinates are too far out
410 Size aMaxXY(pWin->GetOutputSizePixel());
411 long a(2 * nPixSiz);
412 long nMaxX(aMaxXY.Width() + a);
413 long nMaxY(aMaxXY.Height() + a);
415 if (aPixRect.Left ()<-a) aPixRect.Left()=-a;
416 if (aPixRect.Top ()<-a) aPixRect.Top ()=-a;
417 if (aPixRect.Right ()>nMaxX) aPixRect.Right ()=nMaxX;
418 if (aPixRect.Bottom()>nMaxY) aPixRect.Bottom()=nMaxY;
421 Rectangle aOuterPix(aPixRect);
422 aOuterPix.Left()-=nPixSiz;
423 aOuterPix.Top()-=nPixSiz;
424 aOuterPix.Right()+=nPixSiz;
425 aOuterPix.Bottom()+=nPixSiz;
427 bool bMerk(pWin->IsMapModeEnabled());
428 pWin->EnableMapMode(sal_False);
429 pWin->Invalidate(aOuterPix);
430 pWin->EnableMapMode(bMerk);
435 OutlinerView* SdrObjEditView::ImpMakeOutlinerView(Window* pWin, bool /*bNoPaint*/, OutlinerView* pGivenView) const
437 // background
438 Color aBackground(GetTextEditBackgroundColor(*this));
439 SdrTextObj* pText = dynamic_cast< SdrTextObj * >( mxTextEditObj.get() );
440 bool bTextFrame=pText!=NULL && pText->IsTextFrame();
441 bool bContourFrame=pText!=NULL && pText->IsContourTextFrame();
442 // create OutlinerView
443 OutlinerView* pOutlView=pGivenView;
444 pTextEditOutliner->SetUpdateMode(sal_False);
445 if (pOutlView==NULL) pOutlView=new OutlinerView(pTextEditOutliner,pWin);
446 else pOutlView->SetWindow(pWin);
447 // disallow scrolling
448 sal_uIntPtr nStat=pOutlView->GetControlWord();
449 nStat&=~EV_CNTRL_AUTOSCROLL;
450 // AutoViewSize only if not ContourFrame.
451 if (!bContourFrame) nStat|=EV_CNTRL_AUTOSIZE;
452 if (bTextFrame) {
453 sal_uInt16 nPixSiz=aHdl.GetHdlSize()*2+1;
454 nStat|=EV_CNTRL_INVONEMORE;
455 pOutlView->SetInvalidateMore(nPixSiz);
457 pOutlView->SetControlWord(nStat);
458 pOutlView->SetBackgroundColor( aBackground );
459 if (pText!=NULL)
461 pOutlView->SetAnchorMode((EVAnchorMode)(pText->GetOutlinerViewAnchorMode()));
462 pTextEditOutliner->SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)pText->GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
464 // do update before setting output area so that aTextEditArea can be recalculated
465 pTextEditOutliner->SetUpdateMode(sal_True);
466 pOutlView->SetOutputArea(aTextEditArea);
467 ImpInvalidateOutlinerView(*pOutlView);
468 return pOutlView;
471 IMPL_LINK(SdrObjEditView,ImpOutlinerStatusEventHdl,EditStatus*,pEditStat)
473 if(pTextEditOutliner )
475 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj * >( mxTextEditObj.get() );
476 if( pTextObj )
478 pTextObj->onEditOutlinerStatusEvent( pEditStat );
481 return 0;
484 IMPL_LINK(SdrObjEditView,ImpOutlinerCalcFieldValueHdl,EditFieldInfo*,pFI)
486 bool bOk=false;
487 String& rStr=pFI->GetRepresentation();
488 rStr.Erase();
489 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
490 if (pTextObj!=NULL) {
491 Color* pTxtCol=NULL;
492 Color* pFldCol=NULL;
493 bOk=pTextObj->CalcFieldValue(pFI->GetField(),pFI->GetPara(),pFI->GetPos(),sal_True,pTxtCol,pFldCol,rStr);
494 if (bOk) {
495 if (pTxtCol!=NULL) {
496 pFI->SetTxtColor(*pTxtCol);
497 delete pTxtCol;
499 if (pFldCol!=NULL) {
500 pFI->SetFldColor(*pFldCol);
501 delete pFldCol;
502 } else {
503 pFI->SetFldColor(Color(COL_LIGHTGRAY)); // TODO: remove this later on (357)
507 Outliner& rDrawOutl=pMod->GetDrawOutliner(pTextObj);
508 Link aDrawOutlLink=rDrawOutl.GetCalcFieldValueHdl();
509 if (!bOk && aDrawOutlLink.IsSet()) {
510 aDrawOutlLink.Call(pFI);
511 bOk = (sal_Bool)rStr.Len();
513 if (!bOk && aOldCalcFieldValueLink.IsSet()) {
514 return aOldCalcFieldValueLink.Call(pFI);
516 return 0;
519 sal_Bool SdrObjEditView::SdrBeginTextEdit(
520 SdrObject* pObj, SdrPageView* pPV, Window* pWin,
521 sal_Bool bIsNewObj, SdrOutliner* pGivenOutliner,
522 OutlinerView* pGivenOutlinerView,
523 sal_Bool bDontDeleteOutliner, sal_Bool bOnlyOneView,
524 sal_Bool bGrabFocus)
526 SdrEndTextEdit();
528 if( dynamic_cast< SdrTextObj* >( pObj ) == 0 )
529 return sal_False; // currently only possible with text objects
531 if(bGrabFocus && pWin)
533 // attention, this call may cause an EndTextEdit() call to this view
534 pWin->GrabFocus(); // to force the cursor into the edit view
537 bTextEditDontDelete=bDontDeleteOutliner && pGivenOutliner!=NULL;
538 bTextEditOnlyOneView=bOnlyOneView;
539 bTextEditNewObj=bIsNewObj;
540 const sal_uInt32 nWinAnz(PaintWindowCount());
541 sal_uInt32 i;
542 bool bBrk(false);
543 // break, when no object given
545 if(!pObj)
547 bBrk = true;
550 if(!bBrk && !pWin)
552 for(i = 0L; i < nWinAnz && !pWin; i++)
554 SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
556 if(OUTDEV_WINDOW == pPaintWindow->GetOutputDevice().GetOutDevType())
558 pWin = (Window*)(&pPaintWindow->GetOutputDevice());
562 // break, when no window exists
563 if(!pWin)
565 bBrk = true;
569 if(!bBrk && !pPV)
571 pPV = GetSdrPageView();
573 // break, when no PageView for the object exists
574 if(!pPV)
576 bBrk = true;
580 if(pObj && pPV)
582 // no TextEdit on objects in locked Layer
583 if(pPV->GetLockedLayers().IsSet(pObj->GetLayer()))
585 bBrk = true;
589 if(pTextEditOutliner)
591 OSL_FAIL("SdrObjEditView::SdrBeginTextEdit(): Old Outliner still exists.");
592 delete pTextEditOutliner;
593 pTextEditOutliner = 0L;
596 if(!bBrk)
598 pTextEditWin=pWin;
599 pTextEditPV=pPV;
600 mxTextEditObj.reset( pObj );
601 pTextEditOutliner=pGivenOutliner;
602 if (pTextEditOutliner==NULL)
603 pTextEditOutliner = SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, mxTextEditObj->GetModel() );
606 SvtAccessibilityOptions aOptions;
607 pTextEditOutliner->ForceAutoColor( aOptions.GetIsAutomaticFontColor() );
610 bool bEmpty = mxTextEditObj->GetOutlinerParaObject()==NULL;
612 aOldCalcFieldValueLink=pTextEditOutliner->GetCalcFieldValueHdl();
613 // FieldHdl has to be set by SdrBeginTextEdit, because this call an UpdateFields
614 pTextEditOutliner->SetCalcFieldValueHdl(LINK(this,SdrObjEditView,ImpOutlinerCalcFieldValueHdl));
615 pTextEditOutliner->SetBeginPasteOrDropHdl(LINK(this,SdrObjEditView,BeginPasteOrDropHdl));
616 pTextEditOutliner->SetEndPasteOrDropHdl(LINK(this,SdrObjEditView, EndPasteOrDropHdl));
618 // It is just necessary to make the visualized page known. Set it.
619 pTextEditOutliner->setVisualizedPage(pPV ? pPV->GetPage() : 0);
621 pTextEditOutliner->SetTextObjNoInit( dynamic_cast< SdrTextObj* >( mxTextEditObj.get() ) );
623 if(mxTextEditObj->BegTextEdit(*pTextEditOutliner))
625 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
626 DBG_ASSERT( pTextObj, "svx::SdrObjEditView::BegTextEdit(), no text object?" );
627 if( !pTextObj )
628 return sal_False;
630 // switch off any running TextAnimations
631 pTextObj->SetTextAnimationAllowed(sal_False);
633 // remember old cursor
634 if (pTextEditOutliner->GetViewCount()!=0)
636 OutlinerView* pTmpOLV=pTextEditOutliner->RemoveView(static_cast<size_t>(0));
637 if(pTmpOLV!=NULL && pTmpOLV!=pGivenOutlinerView)
638 delete pTmpOLV;
641 // Determine EditArea via TakeTextEditArea.
642 // TODO: This could theoretically be left out, because TakeTextRect() calculates the aTextEditArea,
643 // but aMinTextEditArea has to happen, too (therefore leaving this in right now)
644 pTextObj->TakeTextEditArea(NULL,NULL,&aTextEditArea,&aMinTextEditArea);
646 Rectangle aTextRect;
647 Rectangle aAnchorRect;
648 pTextObj->TakeTextRect(*pTextEditOutliner, aTextRect, sal_True,
649 &aAnchorRect /* Give sal_True here, not sal_False */);
651 if ( !pTextObj->IsContourTextFrame() )
653 // FitToSize not together with ContourFrame, for now
654 if (pTextObj->IsFitToSize())
655 aTextRect = aAnchorRect;
658 aTextEditArea = aTextRect;
660 // Hack for calc, transform position of edit object according
661 // to current zoom so as objects relative position to grid
662 // appears stable
664 Point aPvOfs(pTextObj->GetTextEditOffset());
665 aTextEditArea += pTextObj->GetGridOffset();
666 aTextEditArea.Move(aPvOfs.X(),aPvOfs.Y());
667 aMinTextEditArea += pTextObj->GetGridOffset();
668 aMinTextEditArea.Move(aPvOfs.X(),aPvOfs.Y());
669 pTextEditCursorMerker=pWin->GetCursor();
671 aHdl.SetMoveOutside(sal_True);
673 // #i72757#
674 // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
675 // to call AdjustMarkHdl() always.
676 AdjustMarkHdl();
678 pTextEditOutlinerView=ImpMakeOutlinerView(pWin,!bEmpty,pGivenOutlinerView);
680 // check if this view is already inserted
681 sal_uIntPtr i2,nCount = pTextEditOutliner->GetViewCount();
682 for( i2 = 0; i2 < nCount; i2++ )
684 if( pTextEditOutliner->GetView(i2) == pTextEditOutlinerView )
685 break;
688 if( i2 == nCount )
689 pTextEditOutliner->InsertView(pTextEditOutlinerView,0);
691 aHdl.SetMoveOutside(sal_False);
692 aHdl.SetMoveOutside(sal_True);
694 // register all windows as OutlinerViews with the Outliner
695 if(!bOnlyOneView)
697 for(i = 0L; i < nWinAnz; i++)
699 SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
700 OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
702 if(&rOutDev != pWin && OUTDEV_WINDOW == rOutDev.GetOutDevType())
704 OutlinerView* pOutlView = ImpMakeOutlinerView((Window*)(&rOutDev), !bEmpty, 0L);
705 pTextEditOutliner->InsertView(pOutlView, (sal_uInt16)i);
710 pTextEditOutlinerView->ShowCursor();
711 pTextEditOutliner->SetStatusEventHdl(LINK(this,SdrObjEditView,ImpOutlinerStatusEventHdl));
712 #ifdef DBG_UTIL
713 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
714 #endif
715 pTextEditOutliner->ClearModifyFlag();
717 if(pWin)
719 bool bExtraInvalidate(false);
721 if(!bExtraInvalidate)
723 if(pTextObj->IsFitToSize())
724 bExtraInvalidate = true;
727 if(bExtraInvalidate)
729 pWin->Invalidate(aTextEditArea);
733 if( GetModel() )
735 SdrHint aHint(*pTextObj);
736 aHint.SetKind(HINT_BEGEDIT);
737 GetModel()->Broadcast(aHint);
740 pTextEditOutliner->setVisualizedPage(0);
742 if( mxSelectionController.is() )
743 mxSelectionController->onSelectionHasChanged();
745 return sal_True; // ran fine, let TextEdit run now
747 else
749 bBrk = true;
750 pTextEditOutliner->SetCalcFieldValueHdl(aOldCalcFieldValueLink);
751 pTextEditOutliner->SetBeginPasteOrDropHdl(Link());
752 pTextEditOutliner->SetEndPasteOrDropHdl(Link());
756 if (pTextEditOutliner != NULL)
758 pTextEditOutliner->setVisualizedPage(0);
761 // something went wrong...
762 if(!bDontDeleteOutliner)
764 if(pGivenOutliner!=NULL)
766 delete pGivenOutliner;
767 pTextEditOutliner = NULL;
769 if(pGivenOutlinerView!=NULL)
771 delete pGivenOutlinerView;
772 pGivenOutlinerView = NULL;
775 if( pTextEditOutliner!=NULL )
777 delete pTextEditOutliner;
780 pTextEditOutliner=NULL;
781 pTextEditOutlinerView=NULL;
782 mxTextEditObj.reset(0);
783 pTextEditPV=NULL;
784 pTextEditWin=NULL;
785 aHdl.SetMoveOutside(sal_False);
787 return sal_False;
790 SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally)
792 SdrEndTextEditKind eRet=SDRENDTEXTEDIT_UNCHANGED;
793 SdrTextObj* pTEObj = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
794 Window* pTEWin =pTextEditWin;
795 SdrOutliner* pTEOutliner =pTextEditOutliner;
796 OutlinerView* pTEOutlinerView=pTextEditOutlinerView;
797 Cursor* pTECursorMerker=pTextEditCursorMerker;
799 if( GetModel() && mxTextEditObj.is() )
801 SdrHint aHint(*mxTextEditObj.get());
802 aHint.SetKind(HINT_ENDEDIT);
803 GetModel()->Broadcast(aHint);
806 mxTextEditObj.reset(0);
807 pTextEditPV=NULL;
808 pTextEditWin=NULL;
809 pTextEditOutliner=NULL;
810 pTextEditOutlinerView=NULL;
811 pTextEditCursorMerker=NULL;
812 aTextEditArea=Rectangle();
814 if (pTEOutliner!=NULL)
816 sal_Bool bModified=pTEOutliner->IsModified();
817 if (pTEOutlinerView!=NULL)
819 pTEOutlinerView->HideCursor();
821 if (pTEObj!=NULL)
823 pTEOutliner->CompleteOnlineSpelling();
825 SdrUndoObjSetText* pTxtUndo = 0;
827 if( bModified )
829 sal_Int32 nText;
830 for( nText = 0; nText < pTEObj->getTextCount(); ++nText )
831 if( pTEObj->getText( nText ) == pTEObj->getActiveText() )
832 break;
834 pTxtUndo = dynamic_cast< SdrUndoObjSetText* >( GetModel()->GetSdrUndoFactory().CreateUndoObjectSetText(*pTEObj, nText ) );
836 DBG_ASSERT( !bModified || pTxtUndo, "svx::SdrObjEditView::EndTextEdit(), could not create undo action!" );
837 // Set old CalcFieldValue-Handler again, this
838 // has to happen before Obj::EndTextEdit(), as this does UpdateFields().
839 pTEOutliner->SetCalcFieldValueHdl(aOldCalcFieldValueLink);
840 pTEOutliner->SetBeginPasteOrDropHdl(Link());
841 pTEOutliner->SetEndPasteOrDropHdl(Link());
843 const bool bUndo = IsUndoEnabled();
844 if( bUndo )
846 XubString aObjName;
847 pTEObj->TakeObjNameSingul(aObjName);
848 BegUndo(ImpGetResStr(STR_UndoObjSetText),aObjName);
851 pTEObj->EndTextEdit(*pTEOutliner);
853 if( (pTEObj->GetRotateAngle() != 0) || (pTEObj && pTEObj->ISA(SdrTextObj) && ((SdrTextObj*)pTEObj)->IsFontwork()) )
855 pTEObj->ActionChanged();
858 if (pTxtUndo!=NULL)
860 pTxtUndo->AfterSetText();
861 if (!pTxtUndo->IsDifferent())
863 delete pTxtUndo;
864 pTxtUndo=NULL;
867 // check deletion of entire TextObj
868 SdrUndoAction* pDelUndo=NULL;
869 bool bDelObj=false;
870 SdrTextObj* pTextObj=PTR_CAST(SdrTextObj,pTEObj);
871 if (pTextObj!=NULL && bTextEditNewObj)
873 bDelObj=pTextObj->IsTextFrame() &&
874 !pTextObj->HasText() &&
875 !pTextObj->IsEmptyPresObj() &&
876 !pTextObj->HasFill() &&
877 !pTextObj->HasLine();
879 if(pTEObj->IsInserted() && bDelObj && pTextObj->GetObjInventor()==SdrInventor && !bDontDeleteReally)
881 SdrObjKind eIdent=(SdrObjKind)pTextObj->GetObjIdentifier();
882 if(eIdent==OBJ_TEXT || eIdent==OBJ_TEXTEXT)
884 pDelUndo= GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pTEObj);
888 if (pTxtUndo!=NULL)
890 if( bUndo )
891 AddUndo(pTxtUndo);
892 eRet=SDRENDTEXTEDIT_CHANGED;
894 if (pDelUndo!=NULL)
896 if( bUndo )
898 AddUndo(pDelUndo);
900 else
902 delete pDelUndo;
904 eRet=SDRENDTEXTEDIT_DELETED;
905 DBG_ASSERT(pTEObj->GetObjList()!=NULL,"SdrObjEditView::SdrEndTextEdit(): Fatal: Object edited doesn't have an ObjList!");
906 if (pTEObj->GetObjList()!=NULL)
908 pTEObj->GetObjList()->RemoveObject(pTEObj->GetOrdNum());
909 CheckMarked(); // remove selection immediately...
912 else if (bDelObj)
913 { // for Writer: the app has to do the deletion itself.
914 eRet=SDRENDTEXTEDIT_SHOULDBEDELETED;
917 if( bUndo )
918 EndUndo(); // EndUndo after Remove, in case UndoStack is deleted immediately
920 // Switch on any TextAnimation again after TextEdit
921 if(pTEObj->ISA(SdrTextObj))
923 ((SdrTextObj*)pTEObj)->SetTextAnimationAllowed(sal_True);
926 // #i72757#
927 // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
928 // to call AdjustMarkHdl() always.
929 AdjustMarkHdl();
931 // delete all OutlinerViews
932 for (sal_uIntPtr i=pTEOutliner->GetViewCount(); i>0;)
934 i--;
935 OutlinerView* pOLV=pTEOutliner->GetView(i);
936 sal_uInt16 nMorePix=pOLV->GetInvalidateMore() + 10;
937 Window* pWin=pOLV->GetWindow();
938 Rectangle aRect(pOLV->GetOutputArea());
939 pTEOutliner->RemoveView(i);
940 if (!bTextEditDontDelete || i!=0)
942 // may not own the zeroth one
943 delete pOLV;
945 aRect.Union(aTextEditArea);
946 aRect.Union(aMinTextEditArea);
947 aRect=pWin->LogicToPixel(aRect);
948 aRect.Left()-=nMorePix;
949 aRect.Top()-=nMorePix;
950 aRect.Right()+=nMorePix;
951 aRect.Bottom()+=nMorePix;
952 aRect=pWin->PixelToLogic(aRect);
953 InvalidateOneWin(*pWin,aRect);
954 pWin->SetFillColor();
955 pWin->SetLineColor(COL_BLACK);
956 pWin->DrawPixel(aRect.TopLeft());
957 pWin->DrawPixel(aRect.TopRight());
958 pWin->DrawPixel(aRect.BottomLeft());
959 pWin->DrawPixel(aRect.BottomRight());
961 // and now the Outliner itself
962 if (!bTextEditDontDelete) delete pTEOutliner;
963 else pTEOutliner->Clear();
964 if (pTEWin!=NULL) {
965 pTEWin->SetCursor(pTECursorMerker);
967 aHdl.SetMoveOutside(sal_False);
968 if (eRet!=SDRENDTEXTEDIT_UNCHANGED)
970 GetMarkedObjectListWriteAccess().SetNameDirty();
972 #ifdef DBG_UTIL
973 if (pItemBrowser)
975 GetMarkedObjectListWriteAccess().SetNameDirty();
976 pItemBrowser->SetDirty();
978 #endif
981 if( pTEObj &&
982 pTEObj->GetModel() &&
983 !pTEObj->GetModel()->isLocked() &&
984 pTEObj->GetBroadcaster())
986 SdrHint aHint(HINT_ENDEDIT);
987 aHint.SetObject(pTEObj);
988 ((SfxBroadcaster*)pTEObj->GetBroadcaster())->Broadcast(aHint);
991 return eRet;
994 ////////////////////////////////////////////////////////////////////////////////////////////////////
995 // info about TextEdit. Default is sal_False.
996 bool SdrObjEditView::IsTextEdit() const
998 return mxTextEditObj.is();
1001 // info about TextEditPageView. Default is 0L.
1002 SdrPageView* SdrObjEditView::GetTextEditPageView() const
1004 return pTextEditPV;
1007 ////////////////////////////////////////////////////////////////////////////////////////////////////
1009 OutlinerView* SdrObjEditView::ImpFindOutlinerView(Window* pWin) const
1011 if (pWin==NULL) return NULL;
1012 if (pTextEditOutliner==NULL) return NULL;
1013 OutlinerView* pNewView=NULL;
1014 sal_uIntPtr nWinAnz=pTextEditOutliner->GetViewCount();
1015 for (sal_uIntPtr i=0; i<nWinAnz && pNewView==NULL; i++) {
1016 OutlinerView* pView=pTextEditOutliner->GetView(i);
1017 if (pView->GetWindow()==pWin) pNewView=pView;
1019 return pNewView;
1022 void SdrObjEditView::SetTextEditWin(Window* pWin)
1024 if(mxTextEditObj.is() && pWin!=NULL && pWin!=pTextEditWin)
1026 OutlinerView* pNewView=ImpFindOutlinerView(pWin);
1027 if (pNewView!=NULL && pNewView!=pTextEditOutlinerView)
1029 if (pTextEditOutlinerView!=NULL)
1031 pTextEditOutlinerView->HideCursor();
1033 pTextEditOutlinerView=pNewView;
1034 pTextEditWin=pWin;
1035 pWin->GrabFocus(); // Make the cursor blink here as well
1036 pNewView->ShowCursor();
1037 ImpMakeTextCursorAreaVisible();
1042 sal_Bool SdrObjEditView::IsTextEditHit(const Point& rHit, short nTol) const
1044 sal_Bool bOk=sal_False;
1045 if(mxTextEditObj.is())
1047 nTol=ImpGetHitTolLogic(nTol,NULL);
1048 // only a third of the tolerance here, so handles can be hit well
1049 nTol=nTol/3;
1050 nTol=0; // no hit tolerance here any more
1051 if (!bOk)
1053 Rectangle aEditArea;
1054 OutlinerView* pOLV=pTextEditOutliner->GetView(0);
1055 if (pOLV!=NULL)
1057 aEditArea.Union(pOLV->GetOutputArea());
1059 aEditArea.Left()-=nTol;
1060 aEditArea.Top()-=nTol;
1061 aEditArea.Right()+=nTol;
1062 aEditArea.Bottom()+=nTol;
1063 bOk=aEditArea.IsInside(rHit);
1064 if (bOk)
1065 { // check if any characters were actually hit
1066 Point aPnt(rHit); aPnt-=aEditArea.TopLeft();
1067 long nHitTol = 2000;
1068 OutputDevice* pRef = pTextEditOutliner->GetRefDevice();
1069 if( pRef )
1070 nHitTol = pRef->LogicToLogic( nHitTol, MAP_100TH_MM, pRef->GetMapMode().GetMapUnit() );
1072 bOk = pTextEditOutliner->IsTextPos( aPnt, (sal_uInt16)nHitTol );
1076 return bOk;
1079 sal_Bool SdrObjEditView::IsTextEditFrameHit(const Point& rHit) const
1081 sal_Bool bOk=sal_False;
1082 if(mxTextEditObj.is())
1084 SdrTextObj* pText= dynamic_cast<SdrTextObj*>(mxTextEditObj.get());
1085 OutlinerView* pOLV=pTextEditOutliner->GetView(0);
1086 if( pOLV )
1088 Window* pWin=pOLV->GetWindow();
1089 if (pText!=NULL && pText->IsTextFrame() && pOLV!=NULL && pWin!=NULL) {
1090 sal_uInt16 nPixSiz=pOLV->GetInvalidateMore();
1091 Rectangle aEditArea(aMinTextEditArea);
1092 aEditArea.Union(pOLV->GetOutputArea());
1093 if (!aEditArea.IsInside(rHit)) {
1094 Size aSiz(pWin->PixelToLogic(Size(nPixSiz,nPixSiz)));
1095 aEditArea.Left()-=aSiz.Width();
1096 aEditArea.Top()-=aSiz.Height();
1097 aEditArea.Right()+=aSiz.Width();
1098 aEditArea.Bottom()+=aSiz.Height();
1099 bOk=aEditArea.IsInside(rHit);
1104 return bOk;
1107 ////////////////////////////////////////////////////////////////////////////////////////////////////
1109 sal_Bool SdrObjEditView::KeyInput(const KeyEvent& rKEvt, Window* pWin)
1111 if(pTextEditOutlinerView)
1113 if (pTextEditOutlinerView->PostKeyEvent(rKEvt, pWin))
1115 if( pMod )
1117 if( pTextEditOutliner && pTextEditOutliner->IsModified() )
1118 pMod->SetChanged( sal_True );
1121 if (pWin!=NULL && pWin!=pTextEditWin) SetTextEditWin(pWin);
1122 #ifdef DBG_UTIL
1123 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1124 #endif
1125 ImpMakeTextCursorAreaVisible();
1126 return sal_True;
1129 return SdrGlueEditView::KeyInput(rKEvt,pWin);
1132 sal_Bool SdrObjEditView::MouseButtonDown(const MouseEvent& rMEvt, Window* pWin)
1134 if (pTextEditOutlinerView!=NULL) {
1135 sal_Bool bPostIt=pTextEditOutliner->IsInSelectionMode();
1136 if (!bPostIt) {
1137 Point aPt(rMEvt.GetPosPixel());
1138 if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
1139 else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
1140 bPostIt=IsTextEditHit(aPt,nHitTolLog);
1142 if (bPostIt) {
1143 Point aPixPos(rMEvt.GetPosPixel());
1144 Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
1145 if (aPixPos.X()<aR.Left ()) aPixPos.X()=aR.Left ();
1146 if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
1147 if (aPixPos.Y()<aR.Top ()) aPixPos.Y()=aR.Top ();
1148 if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
1149 MouseEvent aMEvt(aPixPos,rMEvt.GetClicks(),rMEvt.GetMode(),
1150 rMEvt.GetButtons(),rMEvt.GetModifier());
1151 if (pTextEditOutlinerView->MouseButtonDown(aMEvt)) {
1152 if (pWin!=NULL && pWin!=pTextEditWin) SetTextEditWin(pWin);
1153 #ifdef DBG_UTIL
1154 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1155 #endif
1156 ImpMakeTextCursorAreaVisible();
1157 return sal_True;
1161 return SdrGlueEditView::MouseButtonDown(rMEvt,pWin);
1164 sal_Bool SdrObjEditView::MouseButtonUp(const MouseEvent& rMEvt, Window* pWin)
1166 if (pTextEditOutlinerView!=NULL) {
1167 sal_Bool bPostIt=pTextEditOutliner->IsInSelectionMode();
1168 if (!bPostIt) {
1169 Point aPt(rMEvt.GetPosPixel());
1170 if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
1171 else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
1172 bPostIt=IsTextEditHit(aPt,nHitTolLog);
1174 if (bPostIt) {
1175 Point aPixPos(rMEvt.GetPosPixel());
1176 Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
1177 if (aPixPos.X()<aR.Left ()) aPixPos.X()=aR.Left ();
1178 if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
1179 if (aPixPos.Y()<aR.Top ()) aPixPos.Y()=aR.Top ();
1180 if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
1181 MouseEvent aMEvt(aPixPos,rMEvt.GetClicks(),rMEvt.GetMode(),
1182 rMEvt.GetButtons(),rMEvt.GetModifier());
1183 if (pTextEditOutlinerView->MouseButtonUp(aMEvt)) {
1184 #ifdef DBG_UTIL
1185 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1186 #endif
1187 ImpMakeTextCursorAreaVisible();
1188 return sal_True;
1192 return SdrGlueEditView::MouseButtonUp(rMEvt,pWin);
1195 sal_Bool SdrObjEditView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
1197 if (pTextEditOutlinerView!=NULL) {
1198 sal_Bool bSelMode=pTextEditOutliner->IsInSelectionMode();
1199 sal_Bool bPostIt=bSelMode;
1200 if (!bPostIt) {
1201 Point aPt(rMEvt.GetPosPixel());
1202 if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
1203 else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
1204 bPostIt=IsTextEditHit(aPt,nHitTolLog);
1206 if (bPostIt) {
1207 Point aPixPos(rMEvt.GetPosPixel());
1208 Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
1209 if (aPixPos.X()<aR.Left ()) aPixPos.X()=aR.Left ();
1210 if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
1211 if (aPixPos.Y()<aR.Top ()) aPixPos.Y()=aR.Top ();
1212 if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
1213 MouseEvent aMEvt(aPixPos,rMEvt.GetClicks(),rMEvt.GetMode(),
1214 rMEvt.GetButtons(),rMEvt.GetModifier());
1215 if (pTextEditOutlinerView->MouseMove(aMEvt) && bSelMode) {
1216 #ifdef DBG_UTIL
1217 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1218 #endif
1219 ImpMakeTextCursorAreaVisible();
1220 return sal_True;
1224 return SdrGlueEditView::MouseMove(rMEvt,pWin);
1227 sal_Bool SdrObjEditView::Command(const CommandEvent& rCEvt, Window* pWin)
1229 // as long as OutlinerView returns a sal_Bool, it only gets COMMAND_STARTDRAG
1230 if (pTextEditOutlinerView!=NULL)
1232 if (rCEvt.GetCommand()==COMMAND_STARTDRAG) {
1233 sal_Bool bPostIt=pTextEditOutliner->IsInSelectionMode() || !rCEvt.IsMouseEvent();
1234 if (!bPostIt && rCEvt.IsMouseEvent()) {
1235 Point aPt(rCEvt.GetMousePosPixel());
1236 if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
1237 else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
1238 bPostIt=IsTextEditHit(aPt,nHitTolLog);
1240 if (bPostIt) {
1241 Point aPixPos(rCEvt.GetMousePosPixel());
1242 if (rCEvt.IsMouseEvent()) {
1243 Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
1244 if (aPixPos.X()<aR.Left ()) aPixPos.X()=aR.Left ();
1245 if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
1246 if (aPixPos.Y()<aR.Top ()) aPixPos.Y()=aR.Top ();
1247 if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
1249 CommandEvent aCEvt(aPixPos,rCEvt.GetCommand(),rCEvt.IsMouseEvent());
1250 // Command is void at the OutlinerView, sadly
1251 pTextEditOutlinerView->Command(aCEvt);
1252 if (pWin!=NULL && pWin!=pTextEditWin) SetTextEditWin(pWin);
1253 #ifdef DBG_UTIL
1254 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1255 #endif
1256 ImpMakeTextCursorAreaVisible();
1257 return sal_True;
1260 else
1262 pTextEditOutlinerView->Command(rCEvt);
1263 return sal_True;
1266 return SdrGlueEditView::Command(rCEvt,pWin);
1269 ////////////////////////////////////////////////////////////////////////////////////////////////////
1271 sal_Bool SdrObjEditView::ImpIsTextEditAllSelected() const
1273 sal_Bool bRet=sal_False;
1274 if (pTextEditOutliner!=NULL && pTextEditOutlinerView!=NULL)
1276 if(SdrTextObj::HasTextImpl( pTextEditOutliner ) )
1278 const sal_Int32 nParaAnz=pTextEditOutliner->GetParagraphCount();
1279 Paragraph* pLastPara=pTextEditOutliner->GetParagraph( nParaAnz > 1 ? nParaAnz - 1 : 0 );
1281 ESelection aESel(pTextEditOutlinerView->GetSelection());
1282 if (aESel.nStartPara==0 && aESel.nStartPos==0 && aESel.nEndPara==(nParaAnz-1))
1284 XubString aStr(pTextEditOutliner->GetText(pLastPara));
1286 if(aStr.Len() == aESel.nEndPos)
1287 bRet = sal_True;
1289 // in case the selection was done backwards
1290 if (!bRet && aESel.nEndPara==0 && aESel.nEndPos==0 && aESel.nStartPara==(nParaAnz-1))
1292 XubString aStr(pTextEditOutliner->GetText(pLastPara));
1294 if(aStr.Len() == aESel.nStartPos)
1295 bRet = sal_True;
1298 else
1300 bRet=sal_True;
1303 return bRet;
1306 void SdrObjEditView::ImpMakeTextCursorAreaVisible()
1308 if (pTextEditOutlinerView!=NULL && pTextEditWin!=NULL) {
1309 Cursor* pCsr=pTextEditWin->GetCursor();
1310 if (pCsr!=NULL) {
1311 Size aSiz(pCsr->GetSize());
1312 if (aSiz.Width()!=0 && aSiz.Height()!=0) {
1313 MakeVisible(Rectangle(pCsr->GetPos(),aSiz),*pTextEditWin);
1319 sal_uInt16 SdrObjEditView::GetScriptType() const
1321 sal_uInt16 nScriptType = 0;
1323 if( IsTextEdit() )
1325 if( mxTextEditObj->GetOutlinerParaObject() )
1326 nScriptType = mxTextEditObj->GetOutlinerParaObject()->GetTextObject().GetScriptType();
1328 if( pTextEditOutlinerView )
1329 nScriptType = pTextEditOutlinerView->GetSelectedScriptType();
1331 else
1333 sal_uInt32 nMarkCount( GetMarkedObjectCount() );
1335 for( sal_uInt32 i = 0; i < nMarkCount; i++ )
1337 OutlinerParaObject* pParaObj = GetMarkedObjectByIndex( i )->GetOutlinerParaObject();
1339 if( pParaObj )
1341 nScriptType |= pParaObj->GetTextObject().GetScriptType();
1346 if( nScriptType == 0 )
1347 nScriptType = SCRIPTTYPE_LATIN;
1349 return nScriptType;
1352 sal_Bool SdrObjEditView::GetAttributes(SfxItemSet& rTargetSet, sal_Bool bOnlyHardAttr) const
1354 if( mxSelectionController.is() )
1355 if( mxSelectionController->GetAttributes( rTargetSet, bOnlyHardAttr ) )
1356 return sal_True;
1358 if(IsTextEdit())
1360 DBG_ASSERT(pTextEditOutlinerView!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
1361 DBG_ASSERT(pTextEditOutliner!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
1363 // take care of bOnlyHardAttr(!)
1364 if(!bOnlyHardAttr && mxTextEditObj->GetStyleSheet())
1365 rTargetSet.Put(mxTextEditObj->GetStyleSheet()->GetItemSet());
1367 // add object attributes
1368 rTargetSet.Put( mxTextEditObj->GetMergedItemSet() );
1370 if( mxTextEditObj->GetOutlinerParaObject() )
1371 rTargetSet.Put( SvxScriptTypeItem( mxTextEditObj->GetOutlinerParaObject()->GetTextObject().GetScriptType() ) );
1373 if(pTextEditOutlinerView)
1375 // FALSE= regard InvalidItems as "holes," not as Default
1376 rTargetSet.Put(pTextEditOutlinerView->GetAttribs(), sal_False);
1377 rTargetSet.Put( SvxScriptTypeItem( pTextEditOutlinerView->GetSelectedScriptType() ) );
1380 if(GetMarkedObjectCount()==1 && GetMarkedObjectByIndex(0)==mxTextEditObj.get())
1382 MergeNotPersistAttrFromMarked(rTargetSet, bOnlyHardAttr);
1385 return sal_True;
1387 else
1389 return SdrGlueEditView::GetAttributes(rTargetSet, bOnlyHardAttr);
1393 sal_Bool SdrObjEditView::SetAttributes(const SfxItemSet& rSet, sal_Bool bReplaceAll)
1395 sal_Bool bRet=sal_False;
1396 bool bTextEdit=pTextEditOutlinerView!=NULL && mxTextEditObj.is();
1397 sal_Bool bAllTextSelected=ImpIsTextEditAllSelected();
1398 const SfxItemSet* pSet=&rSet;
1400 if (!bTextEdit)
1402 // no TextEdit activw -> all Items to drawing object
1403 if( mxSelectionController.is() )
1404 bRet=mxSelectionController->SetAttributes(*pSet,bReplaceAll );
1406 if( !bRet )
1408 bRet=SdrGlueEditView::SetAttributes(*pSet,bReplaceAll);
1411 else
1413 #ifdef DBG_UTIL
1415 bool bHasEEFeatureItems=false;
1416 SfxItemIter aIter(rSet);
1417 const SfxPoolItem* pItem=aIter.FirstItem();
1418 while (!bHasEEFeatureItems && pItem!=NULL)
1420 if (!IsInvalidItem(pItem))
1422 sal_uInt16 nW=pItem->Which();
1423 if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END)
1424 bHasEEFeatureItems=true;
1427 pItem=aIter.NextItem();
1430 if(bHasEEFeatureItems)
1432 String aMessage;
1433 aMessage.AppendAscii("SdrObjEditView::SetAttributes(): Setting EE_FEATURE items at the SdrView does not make sense! It only leads to overhead and unreadable documents.");
1434 InfoBox(NULL, aMessage).Execute();
1437 #endif
1439 sal_Bool bOnlyEEItems;
1440 bool bNoEEItems=!SearchOutlinerItems(*pSet,bReplaceAll,&bOnlyEEItems);
1441 // everything selected? -> attributes to the border, too
1442 // if no EEItems, attributes to the border only
1443 if (bAllTextSelected || bNoEEItems)
1445 if( mxSelectionController.is() )
1446 bRet=mxSelectionController->SetAttributes(*pSet,bReplaceAll );
1448 if( !bRet )
1450 const bool bUndo = IsUndoEnabled();
1452 if( bUndo )
1454 String aStr;
1455 ImpTakeDescriptionStr(STR_EditSetAttributes,aStr);
1456 BegUndo(aStr);
1457 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj.get()));
1459 // #i43537#
1460 // If this is a text object also rescue the OutlinerParaObject since
1461 // applying attributes to the object may change text layout when
1462 // multiple portions exist with multiple formats. If a OutlinerParaObject
1463 // really exists and needs to be rescued is evaluated in the undo
1464 // implementation itself.
1465 bool bRescueText = dynamic_cast< SdrTextObj* >(mxTextEditObj.get());
1467 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*mxTextEditObj.get(),false,!bNoEEItems || bRescueText));
1468 EndUndo();
1471 mxTextEditObj->SetMergedItemSetAndBroadcast(*pSet, bReplaceAll);
1473 FlushComeBackTimer(); // to set ModeHasChanged immediately
1474 bRet=sal_True;
1477 else if (!bOnlyEEItems)
1479 // Otherwise split Set, if necessary.
1480 // Now we build an ItemSet aSet that doesn't contain EE_Items from
1481 // *pSet (otherwise it would be a copy).
1482 sal_uInt16* pNewWhichTable=RemoveWhichRange(pSet->GetRanges(),EE_ITEMS_START,EE_ITEMS_END);
1483 SfxItemSet aSet(pMod->GetItemPool(),pNewWhichTable);
1484 delete[] pNewWhichTable;
1485 SfxWhichIter aIter(aSet);
1486 sal_uInt16 nWhich=aIter.FirstWhich();
1487 while (nWhich!=0)
1489 const SfxPoolItem* pItem;
1490 SfxItemState eState=pSet->GetItemState(nWhich,sal_False,&pItem);
1491 if (eState==SFX_ITEM_SET) aSet.Put(*pItem);
1492 nWhich=aIter.NextWhich();
1496 if( mxSelectionController.is() )
1497 bRet=mxSelectionController->SetAttributes(aSet,bReplaceAll );
1499 if( !bRet )
1501 if( IsUndoEnabled() )
1503 String aStr;
1504 ImpTakeDescriptionStr(STR_EditSetAttributes,aStr);
1505 BegUndo(aStr);
1506 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj.get()));
1507 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*mxTextEditObj.get(),false,false));
1508 EndUndo();
1511 mxTextEditObj->SetMergedItemSetAndBroadcast(aSet, bReplaceAll);
1513 if (GetMarkedObjectCount()==1 && GetMarkedObjectByIndex(0)==mxTextEditObj.get())
1515 SetNotPersistAttrToMarked(aSet,bReplaceAll);
1518 FlushComeBackTimer();
1519 bRet=sal_True;
1521 if(!bNoEEItems)
1523 // and now the attributes to the EditEngine
1524 if (bReplaceAll) {
1525 pTextEditOutlinerView->RemoveAttribs( sal_True );
1527 pTextEditOutlinerView->SetAttribs(rSet);
1529 #ifdef DBG_UTIL
1530 if (pItemBrowser!=NULL)
1531 pItemBrowser->SetDirty();
1532 #endif
1534 ImpMakeTextCursorAreaVisible();
1536 bRet=sal_True;
1538 return bRet;
1541 SfxStyleSheet* SdrObjEditView::GetStyleSheet() const
1543 SfxStyleSheet* pSheet = 0;
1545 if( mxSelectionController.is() )
1547 if( mxSelectionController->GetStyleSheet( pSheet ) )
1548 return pSheet;
1551 if ( pTextEditOutlinerView )
1553 pSheet = pTextEditOutlinerView->GetStyleSheet();
1555 else
1557 pSheet = SdrGlueEditView::GetStyleSheet();
1559 return pSheet;
1562 sal_Bool SdrObjEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr)
1564 if( mxSelectionController.is() )
1566 if( mxSelectionController->SetStyleSheet( pStyleSheet, bDontRemoveHardAttr ) )
1567 return sal_True;
1570 // if we are currently in edit mode we must also set the stylesheet
1571 // on all paragraphs in the Outliner for the edit view
1572 if( NULL != pTextEditOutlinerView )
1574 Outliner* pOutliner = pTextEditOutlinerView->GetOutliner();
1576 const sal_Int32 nParaCount = pOutliner->GetParagraphCount();
1577 for( sal_Int32 nPara = 0; nPara < nParaCount; nPara++ )
1579 pOutliner->SetStyleSheet( nPara, pStyleSheet );
1583 return SdrGlueEditView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
1586 ////////////////////////////////////////////////////////////////////////////////////////////////////
1588 void SdrObjEditView::AddWindowToPaintView(OutputDevice* pNewWin)
1590 SdrGlueEditView::AddWindowToPaintView(pNewWin);
1592 if(mxTextEditObj.is() && !bTextEditOnlyOneView && pNewWin->GetOutDevType()==OUTDEV_WINDOW)
1594 OutlinerView* pOutlView=ImpMakeOutlinerView((Window*)pNewWin,false,NULL);
1595 pTextEditOutliner->InsertView(pOutlView);
1599 void SdrObjEditView::DeleteWindowFromPaintView(OutputDevice* pOldWin)
1601 SdrGlueEditView::DeleteWindowFromPaintView(pOldWin);
1603 if(mxTextEditObj.is() && !bTextEditOnlyOneView && pOldWin->GetOutDevType()==OUTDEV_WINDOW)
1605 for (sal_uIntPtr i=pTextEditOutliner->GetViewCount(); i>0;) {
1606 i--;
1607 OutlinerView* pOLV=pTextEditOutliner->GetView(i);
1608 if (pOLV && pOLV->GetWindow()==(Window*)pOldWin) {
1609 delete pTextEditOutliner->RemoveView(i);
1615 sal_Bool SdrObjEditView::IsTextEditInSelectionMode() const
1617 return pTextEditOutliner!=NULL && pTextEditOutliner->IsInSelectionMode();
1620 ////////////////////////////////////////////////////////////////////////////////////////////////////
1621 // MacroMode
1622 ////////////////////////////////////////////////////////////////////////////////////////////////////
1624 sal_Bool SdrObjEditView::BegMacroObj(const Point& rPnt, short nTol, SdrObject* pObj, SdrPageView* pPV, Window* pWin)
1626 sal_Bool bRet=sal_False;
1627 BrkMacroObj();
1628 if (pObj!=NULL && pPV!=NULL && pWin!=NULL && pObj->HasMacro()) {
1629 nTol=ImpGetHitTolLogic(nTol,NULL);
1630 pMacroObj=pObj;
1631 pMacroPV=pPV;
1632 pMacroWin=pWin;
1633 bMacroDown=sal_False;
1634 nMacroTol=sal_uInt16(nTol);
1635 aMacroDownPos=rPnt;
1636 MovMacroObj(rPnt);
1638 return bRet;
1641 void SdrObjEditView::ImpMacroUp(const Point& rUpPos)
1643 if (pMacroObj!=NULL && bMacroDown)
1645 SdrObjMacroHitRec aHitRec;
1646 aHitRec.aPos=rUpPos;
1647 aHitRec.aDownPos=aMacroDownPos;
1648 aHitRec.nTol=nMacroTol;
1649 aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
1650 aHitRec.pPageView=pMacroPV;
1651 aHitRec.pOut=pMacroWin;
1652 pMacroObj->PaintMacro(*pMacroWin,Rectangle(),aHitRec);
1653 bMacroDown=sal_False;
1657 void SdrObjEditView::ImpMacroDown(const Point& rDownPos)
1659 if (pMacroObj!=NULL && !bMacroDown)
1661 SdrObjMacroHitRec aHitRec;
1662 aHitRec.aPos=rDownPos;
1663 aHitRec.aDownPos=aMacroDownPos;
1664 aHitRec.nTol=nMacroTol;
1665 aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
1666 aHitRec.pPageView=pMacroPV;
1667 aHitRec.bDown=sal_True;
1668 aHitRec.pOut=pMacroWin;
1669 pMacroObj->PaintMacro(*pMacroWin,Rectangle(),aHitRec);
1670 bMacroDown=sal_True;
1674 void SdrObjEditView::MovMacroObj(const Point& rPnt)
1676 if (pMacroObj!=NULL) {
1677 SdrObjMacroHitRec aHitRec;
1678 aHitRec.aPos=rPnt;
1679 aHitRec.aDownPos=aMacroDownPos;
1680 aHitRec.nTol=nMacroTol;
1681 aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
1682 aHitRec.pPageView=pMacroPV;
1683 aHitRec.bDown=bMacroDown;
1684 aHitRec.pOut=pMacroWin;
1685 sal_Bool bDown=pMacroObj->IsMacroHit(aHitRec);
1686 if (bDown) ImpMacroDown(rPnt);
1687 else ImpMacroUp(rPnt);
1691 void SdrObjEditView::BrkMacroObj()
1693 if (pMacroObj!=NULL) {
1694 ImpMacroUp(aMacroDownPos);
1695 pMacroObj=NULL;
1696 pMacroPV=NULL;
1697 pMacroWin=NULL;
1701 sal_Bool SdrObjEditView::EndMacroObj()
1703 if (pMacroObj!=NULL && bMacroDown) {
1704 ImpMacroUp(aMacroDownPos);
1705 SdrObjMacroHitRec aHitRec;
1706 aHitRec.aPos=aMacroDownPos;
1707 aHitRec.aDownPos=aMacroDownPos;
1708 aHitRec.nTol=nMacroTol;
1709 aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
1710 aHitRec.pPageView=pMacroPV;
1711 aHitRec.bDown=sal_True;
1712 aHitRec.pOut=pMacroWin;
1713 bool bRet=pMacroObj->DoMacro(aHitRec);
1714 pMacroObj=NULL;
1715 pMacroPV=NULL;
1716 pMacroWin=NULL;
1717 return bRet;
1718 } else {
1719 BrkMacroObj();
1720 return sal_False;
1724 /** fills the given any with a XTextCursor for the current text selection.
1725 Leaves the any untouched if there currently is no text selected */
1726 void SdrObjEditView::getTextSelection( ::com::sun::star::uno::Any& rSelection )
1728 if( IsTextEdit() )
1730 OutlinerView* pOutlinerView = GetTextEditOutlinerView();
1731 if( pOutlinerView && pOutlinerView->HasSelection() )
1733 SdrObject* pObj = GetTextEditObject();
1735 if( pObj )
1737 ::com::sun::star::uno::Reference< ::com::sun::star::text::XText > xText( pObj->getUnoShape(), ::com::sun::star::uno::UNO_QUERY );
1738 if( xText.is() )
1740 SvxUnoTextBase* pRange = SvxUnoTextBase::getImplementation( xText );
1741 if( pRange )
1743 rSelection <<= pRange->createTextCursorBySelection( pOutlinerView->GetSelection() );
1751 namespace sdr { namespace table {
1752 extern rtl::Reference< sdr::SelectionController > CreateTableController( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController );
1755 /* check if we have a single selection and that single object likes
1756 to handle the mouse and keyboard events itself
1758 TODO: the selection controller should be queried from the
1759 object specific view contact. Currently this method only
1760 works for tables.
1762 void SdrObjEditView::MarkListHasChanged()
1764 SdrGlueEditView::MarkListHasChanged();
1766 if( mxSelectionController.is() )
1768 mxLastSelectionController = mxSelectionController;
1769 mxSelectionController->onSelectionHasChanged();
1772 mxSelectionController.clear();
1774 const SdrMarkList& rMarkList=GetMarkedObjectList();
1775 if( rMarkList.GetMarkCount() == 1 )
1777 const SdrObject* pObj= rMarkList.GetMark(0)->GetMarkedSdrObj();
1778 // check for table
1779 if( pObj && (pObj->GetObjInventor() == SdrInventor ) && (pObj->GetObjIdentifier() == OBJ_TABLE) )
1781 mxSelectionController = sdr::table::CreateTableController( this, pObj, mxLastSelectionController );
1782 if( mxSelectionController.is() )
1784 mxLastSelectionController.clear();
1785 mxSelectionController->onSelectionHasChanged();
1791 IMPL_LINK( SdrObjEditView, EndPasteOrDropHdl, PasteOrDropInfos*, pInfos )
1793 OnEndPasteOrDrop( pInfos );
1794 return 0;
1797 IMPL_LINK( SdrObjEditView, BeginPasteOrDropHdl, PasteOrDropInfos*, pInfos )
1799 OnBeginPasteOrDrop( pInfos );
1800 return 0;
1803 void SdrObjEditView::OnBeginPasteOrDrop( PasteOrDropInfos* )
1805 // applications can derive from these virtual methods to do something before a drop or paste operation
1808 void SdrObjEditView::OnEndPasteOrDrop( PasteOrDropInfos* )
1810 // applications can derive from these virtual methods to do something before a drop or paste operation
1813 sal_uInt16 SdrObjEditView::GetSelectionLevel() const
1815 sal_uInt16 nLevel = 0xFFFF;
1816 if( IsTextEdit() )
1818 DBG_ASSERT(pTextEditOutlinerView!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
1819 DBG_ASSERT(pTextEditOutliner!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
1820 if( pTextEditOutlinerView )
1822 //start and end position
1823 ESelection aSelect = pTextEditOutlinerView->GetSelection();
1824 sal_uInt16 nStartPara = ::std::min( aSelect.nStartPara, aSelect.nEndPara );
1825 sal_uInt16 nEndPara = ::std::max( aSelect.nStartPara, aSelect.nEndPara );
1826 //get level from each paragraph
1827 nLevel = 0;
1828 for( sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++ )
1830 sal_uInt16 nParaDepth = 1 << pTextEditOutliner->GetDepth( nPara );
1831 if( !(nLevel & nParaDepth) )
1832 nLevel += nParaDepth;
1834 //reduce one level for Outliner Object
1835 //if( nLevel > 0 && GetTextEditObject()->GetObjIdentifier() == OBJ_OUTLINETEXT )
1836 // nLevel = nLevel >> 1;
1837 //no bullet paragraph selected
1838 if( nLevel == 0)
1839 nLevel = 0xFFFF;
1842 return nLevel;
1845 bool SdrObjEditView::SupportsFormatPaintbrush( sal_uInt32 nObjectInventor, sal_uInt16 nObjectIdentifier ) const
1847 if( nObjectInventor != SdrInventor && nObjectInventor != E3dInventor )
1848 return false;
1849 switch(nObjectIdentifier)
1851 case OBJ_NONE:
1852 case OBJ_GRUP:
1853 return false;
1854 case OBJ_LINE:
1855 case OBJ_RECT:
1856 case OBJ_CIRC:
1857 case OBJ_SECT:
1858 case OBJ_CARC:
1859 case OBJ_CCUT:
1860 case OBJ_POLY:
1861 case OBJ_PLIN:
1862 case OBJ_PATHLINE:
1863 case OBJ_PATHFILL:
1864 case OBJ_FREELINE:
1865 case OBJ_FREEFILL:
1866 case OBJ_SPLNLINE:
1867 case OBJ_SPLNFILL:
1868 case OBJ_TEXT:
1869 case OBJ_TEXTEXT:
1870 case OBJ_TITLETEXT:
1871 case OBJ_OUTLINETEXT:
1872 case OBJ_GRAF:
1873 case OBJ_OLE2:
1874 case OBJ_TABLE:
1875 return true;
1876 case OBJ_EDGE:
1877 case OBJ_CAPTION:
1878 return false;
1879 case OBJ_PATHPOLY:
1880 case OBJ_PATHPLIN:
1881 return true;
1882 case OBJ_PAGE:
1883 case OBJ_MEASURE:
1884 case OBJ_DUMMY:
1885 case OBJ_FRAME:
1886 case OBJ_UNO:
1887 return false;
1888 case OBJ_CUSTOMSHAPE:
1889 return true;
1890 default:
1891 return false;
1895 static const sal_uInt16* GetFormatRangeImpl( bool bTextOnly )
1897 static const sal_uInt16 gRanges[] = {
1898 SDRATTR_SHADOW_FIRST, SDRATTR_SHADOW_LAST,
1899 SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST,
1900 SDRATTR_TABLE_FIRST, SDRATTR_TABLE_LAST,
1901 XATTR_LINE_FIRST, XATTR_LINE_LAST,
1902 XATTR_FILL_FIRST, XATTRSET_FILL,
1903 EE_PARA_START, EE_PARA_END,
1904 EE_CHAR_START, EE_CHAR_END,
1907 return &gRanges[ bTextOnly ? 10 : 0];
1910 bool SdrObjEditView::TakeFormatPaintBrush( boost::shared_ptr< SfxItemSet >& rFormatSet )
1912 if( mxSelectionController.is() && mxSelectionController->TakeFormatPaintBrush(rFormatSet) )
1913 return true;
1915 const SdrMarkList& rMarkList = GetMarkedObjectList();
1916 if( rMarkList.GetMarkCount() >= 1 )
1918 OutlinerView* pOLV = GetTextEditOutlinerView();
1920 rFormatSet.reset( new SfxItemSet( GetModel()->GetItemPool(), GetFormatRangeImpl( pOLV != NULL ) ) );
1921 if( pOLV )
1923 rFormatSet->Put( pOLV->GetAttribs() );
1925 else
1927 const sal_Bool bOnlyHardAttr = sal_False;
1928 rFormatSet->Put( GetAttrFromMarked(bOnlyHardAttr) );
1930 return true;
1933 return false;
1936 static SfxItemSet CreatePaintSet( const sal_uInt16 *pRanges, SfxItemPool& rPool, const SfxItemSet& rSourceSet, const SfxItemSet& rTargetSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
1938 SfxItemSet aPaintSet( rPool, pRanges );
1940 while( *pRanges )
1942 sal_uInt16 nWhich = *pRanges++;
1943 const sal_uInt16 nLastWhich = *pRanges++;
1945 if( bNoCharacterFormats && (nWhich == EE_CHAR_START) )
1946 continue;
1948 if( bNoParagraphFormats && (nWhich == EE_PARA_START ) )
1949 continue;
1951 for( ; nWhich < nLastWhich; nWhich++ )
1953 const SfxPoolItem* pSourceItem = rSourceSet.GetItem( nWhich );
1954 const SfxPoolItem* pTargetItem = rTargetSet.GetItem( nWhich );
1956 if( (pSourceItem && !pTargetItem) || (pSourceItem && pTargetItem && !((*pSourceItem) == (*pTargetItem)) ) )
1958 aPaintSet.Put( *pSourceItem );
1962 return aPaintSet;
1965 void SdrObjEditView::ApplyFormatPaintBrushToText( SfxItemSet& rFormatSet, SdrTextObj& rTextObj, SdrText* pText, bool bNoCharacterFormats, bool bNoParagraphFormats )
1967 OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : 0;
1968 if(pParaObj)
1970 SdrOutliner& rOutliner = rTextObj.ImpGetDrawOutliner();
1971 rOutliner.SetText(*pParaObj);
1973 sal_Int32 nParaCount(rOutliner.GetParagraphCount());
1975 if(nParaCount)
1977 for(sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
1979 if( !bNoCharacterFormats )
1980 rOutliner.QuickRemoveCharAttribs( nPara, /* remove all */0 );
1982 SfxItemSet aSet(rOutliner.GetParaAttribs(nPara));
1983 aSet.Put(CreatePaintSet( GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet, bNoCharacterFormats, bNoParagraphFormats ) );
1984 rOutliner.SetParaAttribs(nPara, aSet);
1987 OutlinerParaObject* pTemp = rOutliner.CreateParaObject(0, nParaCount);
1988 rOutliner.Clear();
1990 rTextObj.NbcSetOutlinerParaObjectForText(pTemp,pText);
1995 void SdrObjEditView::ApplyFormatPaintBrush( SfxItemSet& rFormatSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
1997 if( !mxSelectionController.is() || !mxSelectionController->ApplyFormatPaintBrush( rFormatSet, bNoCharacterFormats, bNoParagraphFormats ) )
1999 const SdrMarkList& rMarkList = GetMarkedObjectList();
2000 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2001 OutlinerView* pOLV = GetTextEditOutlinerView();
2003 const SfxItemSet& rShapeSet = pObj->GetMergedItemSet();
2005 if( !pOLV )
2007 // if not in text edit mode (aka the user selected text or clicked on a word)
2008 // apply formatting attributes to selected shape
2009 // All formatting items (see ranges above) that are unequal in selected shape and
2010 // the format paintbrush are hard set on the selected shape.
2012 const sal_uInt16* pRanges = rFormatSet.GetRanges();
2013 bool bTextOnly = true;
2015 while( *pRanges )
2017 if( (*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START) )
2019 bTextOnly = false;
2020 break;
2022 pRanges += 2;
2025 if( !bTextOnly )
2027 SfxItemSet aPaintSet( CreatePaintSet( GetFormatRangeImpl(false), *rShapeSet.GetPool(), rFormatSet, rShapeSet, bNoCharacterFormats, bNoParagraphFormats ) );
2028 const sal_Bool bReplaceAll = sal_False;
2029 SetAttrToMarked(aPaintSet, bReplaceAll);
2032 // now apply character and paragraph formatting to text, if the shape has any
2033 SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(pObj);
2034 if( pTextObj )
2036 sal_Int32 nText = pTextObj->getTextCount();
2038 while( --nText >= 0 )
2040 SdrText* pText = pTextObj->getText( nText );
2041 ApplyFormatPaintBrushToText( rFormatSet, *pTextObj, pText, bNoCharacterFormats, bNoParagraphFormats );
2045 else
2047 ::Outliner* pOutliner = pOLV->GetOutliner();
2048 if( pOutliner )
2050 const EditEngine& rEditEngine = pOutliner->GetEditEngine();
2052 ESelection aSel( pOLV->GetSelection() );
2053 if( !aSel.HasRange() )
2054 pOLV->SetSelection( rEditEngine.GetWord( aSel, com::sun::star::i18n::WordType::DICTIONARY_WORD ) );
2056 const sal_Bool bRemoveParaAttribs = !bNoParagraphFormats;
2057 pOLV->RemoveAttribsKeepLanguages( bRemoveParaAttribs );
2058 SfxItemSet aSet( pOLV->GetAttribs() );
2059 SfxItemSet aPaintSet( CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet, bNoCharacterFormats, bNoParagraphFormats ) );
2060 pOLV->SetAttribs( aPaintSet );
2066 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */