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 "futext.hxx"
21 : #include <editeng/eeitem.hxx>
22 : #include <editeng/editerr.hxx>
23 : #include <svx/dlgutil.hxx>
24 : #include <svx/svxerr.hxx>
25 : #include <tools/urlobj.hxx>
26 : #include <vcl/help.hxx>
27 : #include <editeng/editstat.hxx>
28 : #include <svl/aeitem.hxx>
29 : #include <svl/intitem.hxx>
30 : #include <svx/svdotext.hxx>
31 : #include <svx/svdogrp.hxx>
32 : #include <editeng/flditem.hxx>
33 : #include <svl/style.hxx>
34 : #include <svx/svdpagv.hxx>
35 : #include <sfx2/viewfrm.hxx>
36 : #include <sfx2/dispatch.hxx>
37 : #include <sfx2/bindings.hxx>
38 : #include <sfx2/request.hxx>
39 : #include <editeng/editeng.hxx>
40 : #include <svx/svdoutl.hxx>
41 : #include <svx/svxids.hrc>
42 : #include <sfx2/docfile.hxx>
43 : #include <comphelper/processfactory.hxx>
44 : #include <editeng/outlobj.hxx>
45 : #include <svtools/langtab.hxx>
46 :
47 : #include <editeng/frmdiritem.hxx>
48 :
49 : #include <svx/svdetc.hxx>
50 : #include <editeng/editview.hxx>
51 :
52 : #include "sdresid.hxx"
53 : #include "app.hrc"
54 : #include "res_bmp.hrc"
55 : #include "ViewShell.hxx"
56 : #include "ViewShellBase.hxx"
57 : #include "View.hxx"
58 : #include "Outliner.hxx"
59 : #include "Window.hxx"
60 : #include "drawdoc.hxx"
61 : #include "sdpage.hxx"
62 : #include "sdmod.hxx"
63 : #include "FrameView.hxx"
64 : #include "ToolBarManager.hxx"
65 : #include "DrawDocShell.hxx"
66 : #include "glob.hrc"
67 : #include "pres.hxx"
68 : #include "optsitem.hxx"
69 :
70 : using namespace ::com::sun::star;
71 : using namespace ::com::sun::star::uno;
72 : using namespace ::com::sun::star::lang;
73 : using namespace ::com::sun::star::linguistic2;
74 :
75 : namespace sd {
76 :
77 : static sal_uInt16 SidArray[] = {
78 : SID_STYLE_FAMILY2, // 5542
79 : SID_STYLE_FAMILY5, // 5545
80 : SID_REDO, // 5700
81 : SID_UNDO, // 5701
82 : SID_CUT, // 5710
83 : SID_COPY, // 5711
84 : SID_ATTR_TABSTOP, // 10002
85 : SID_ATTR_CHAR_FONT, // 10007
86 : SID_ATTR_CHAR_POSTURE, // 10008
87 : SID_ATTR_CHAR_WEIGHT, // 10009
88 : SID_ATTR_CHAR_SHADOWED, // 10010
89 : SID_ATTR_CHAR_STRIKEOUT, // 10013
90 : SID_ATTR_CHAR_UNDERLINE, // 10014
91 : SID_ATTR_CHAR_FONTHEIGHT, // 10015
92 : SID_ATTR_CHAR_COLOR, // 10017
93 : SID_ATTR_CHAR_KERNING, // 10018
94 : SID_ATTR_CHAR_CASEMAP, // 10019
95 : SID_ATTR_PARA_ADJUST_LEFT, // 10028
96 : SID_ATTR_PARA_ADJUST_RIGHT, // 10029
97 : SID_ATTR_PARA_ADJUST_CENTER, // 10030
98 : SID_ATTR_PARA_ADJUST_BLOCK, // 10031
99 : SID_ATTR_PARA_LINESPACE_10, // 10034
100 : SID_ATTR_PARA_LINESPACE_15, // 10035
101 : SID_ATTR_PARA_LINESPACE_20, // 10036
102 : SID_ATTR_PARA_ULSPACE, // 10042
103 : SID_ATTR_PARA_LRSPACE, // 10043
104 : SID_ATTR_TRANSFORM_POS_X, // 10088
105 : SID_ATTR_TRANSFORM_POS_Y, // 10089
106 : SID_ATTR_TRANSFORM_WIDTH, // 10090
107 : SID_ATTR_TRANSFORM_HEIGHT,// 10091
108 : SID_ATTR_TRANSFORM_ROT_X, // 10093
109 : SID_ATTR_TRANSFORM_ROT_Y, // 10094
110 : SID_ATTR_TRANSFORM_ANGLE, // 10095 //Added
111 : SID_OUTLINE_UP, // 10150
112 : SID_OUTLINE_DOWN, // 10151
113 : SID_OUTLINE_LEFT, // 10152
114 : SID_OUTLINE_RIGHT, // 10153
115 : SID_ATTR_TRANSFORM_PROTECT_POS,// 10236
116 : SID_ATTR_TRANSFORM_PROTECT_SIZE,// 10237 //Added
117 : SID_FORMTEXT_STYLE, // 10257
118 : SID_SET_SUPER_SCRIPT, // 10294
119 : SID_SET_SUB_SCRIPT, // 10295
120 : SID_ATTR_TRANSFORM_AUTOWIDTH,// 10310
121 : SID_ATTR_TRANSFORM_AUTOHEIGHT,// 10311 //Added
122 : SID_HYPERLINK_GETLINK, // 10361
123 : SID_CHARMAP, // 10503
124 : SID_TEXTDIRECTION_LEFT_TO_RIGHT, // 10907
125 : SID_TEXTDIRECTION_TOP_TO_BOTTOM, // 10908
126 : SID_ATTR_PARA_LEFT_TO_RIGHT, // 10950
127 : SID_ATTR_PARA_RIGHT_TO_LEFT, // 10951
128 : FN_NUM_BULLET_ON, // 20138
129 : SID_PARASPACE_INCREASE, // 27346
130 : SID_PARASPACE_DECREASE, // 27347
131 : 0 };
132 :
133 0 : TYPEINIT1( FuText, FuConstruct );
134 :
135 : static bool bTestText = false;
136 :
137 : /**
138 : * base class for text functions
139 : */
140 3 : FuText::FuText( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
141 : : FuConstruct(pViewSh, pWin, pView, pDoc, rReq)
142 : , bFirstObjCreated(false)
143 : , bJustEndedEdit(false)
144 3 : , rRequest (rReq)
145 : {
146 3 : }
147 :
148 3 : rtl::Reference<FuPoor> FuText::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
149 : {
150 3 : rtl::Reference<FuPoor> xFunc( new FuText( pViewSh, pWin, pView, pDoc, rReq ) );
151 3 : return xFunc;
152 : }
153 :
154 : /** Destruktor */
155 3 : void FuText::disposing()
156 : {
157 3 : if(mpView)
158 : {
159 3 : if(mpView->SdrEndTextEdit(false) == SDRENDTEXTEDIT_DELETED)
160 0 : mxTextObj.reset( 0 );
161 :
162 : // reset the RequestHandler of the used Outliner to the handler of the document
163 3 : ::Outliner* pOutliner = mpView->GetTextEditOutliner();
164 :
165 3 : if (pOutliner)
166 0 : pOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(mpDoc->GetStyleSheetPool()));
167 : }
168 3 : }
169 :
170 : /*************************************************************************
171 : |*
172 : |* Execute functionality of this class:
173 : |*
174 : |* #71422: Start the functionality of this class in this method
175 : |* and not in the ctor.
176 : |* If you construct an object of this class and you put the
177 : |* address of this object to pFuActual you've got a problem,
178 : |* because some methods inside DoExecute use the pFuActual-Pointer.
179 : |* If the code inside DoExecute is executed inside the ctor,
180 : |* the value of pFuActual is not right. And the value will not
181 : |* be right until the ctor finished !!!
182 : |*
183 : \************************************************************************/
184 3 : void FuText::DoExecute( SfxRequest& )
185 : {
186 3 : mpViewShell->GetViewShellBase().GetToolBarManager()->SetToolBarShell(
187 : ToolBarManager::TBG_FUNCTION,
188 3 : RID_DRAW_TEXT_TOOLBOX);
189 :
190 3 : mpView->SetCurrentObj(OBJ_TEXT);
191 3 : mpView->SetEditMode(SDREDITMODE_EDIT);
192 :
193 3 : MouseEvent aMEvt(mpWindow->GetPointerPosPixel());
194 :
195 3 : if (nSlotId == SID_TEXTEDIT)
196 : {
197 : // Try to select an object
198 1 : SdrPageView* pPV = mpView->GetSdrPageView();
199 1 : SdrViewEvent aVEvt;
200 1 : mpView->PickAnything(aMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
201 1 : mpView->MarkObj(aVEvt.pRootObj, pPV);
202 :
203 1 : mxTextObj.reset( dynamic_cast< SdrTextObj* >( aVEvt.pObj ) );
204 : }
205 2 : else if (mpView->AreObjectsMarked())
206 : {
207 2 : const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
208 :
209 2 : if (rMarkList.GetMarkCount() == 1)
210 : {
211 2 : SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
212 2 : mxTextObj.reset( dynamic_cast< SdrTextObj* >( pObj ) );
213 : }
214 : }
215 :
216 : // check for table
217 3 : if (mpView->AreObjectsMarked())
218 : {
219 2 : const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
220 :
221 2 : if (rMarkList.GetMarkCount() == 1)
222 : {
223 2 : SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
224 2 : if( pObj && (pObj->GetObjInventor() == SdrInventor ) && (pObj->GetObjIdentifier() == OBJ_TABLE) )
225 : {
226 0 : mpViewShell->GetViewShellBase().GetToolBarManager()->AddToolBarShell( ToolBarManager::TBG_FUNCTION, RID_DRAW_TABLE_TOOLBOX );
227 : }
228 : }
229 : }
230 :
231 3 : bool bQuickDrag = true;
232 :
233 3 : const SfxItemSet* pArgs = rRequest.GetArgs();
234 :
235 3 : if (pArgs
236 :
237 : // test for type before using
238 3 : && SID_TEXTEDIT == nSlotId
239 1 : && SfxItemState::SET == pArgs->GetItemState(SID_TEXTEDIT)
240 :
241 4 : && (sal_uInt16)static_cast<const SfxUInt16Item&>(pArgs->Get(SID_TEXTEDIT)).GetValue() == 2)
242 : {
243 : // Selection by doubleclick -> don't allow QuickDrag
244 0 : bQuickDrag = false;
245 : }
246 :
247 3 : SetInEditMode(aMEvt, bQuickDrag);
248 3 : }
249 :
250 1 : bool FuText::MouseButtonDown(const MouseEvent& rMEvt)
251 : {
252 1 : bMBDown = true;
253 1 : bJustEndedEdit = false;
254 :
255 1 : bool bReturn = FuDraw::MouseButtonDown(rMEvt);
256 :
257 1 : mpView->SetMarkHdlWhenTextEdit(true);
258 1 : SdrViewEvent aVEvt;
259 1 : SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
260 :
261 1 : if (eHit == SDRHIT_TEXTEDIT)
262 : {
263 : // hit text -> SdrView handles event
264 1 : if (mpView->MouseButtonDown(rMEvt, mpWindow))
265 1 : return true;
266 : }
267 :
268 0 : if (rMEvt.GetClicks() == 1)
269 : {
270 0 : if (mpView->IsTextEdit() && eHit != SDRHIT_MARKEDOBJECT && eHit != SDRHIT_HANDLE)
271 : {
272 : // finish text input
273 0 : if(mpView->SdrEndTextEdit() == SDRENDTEXTEDIT_DELETED)
274 : {
275 : /* Bugfix from MBA: during a double click onto the unused? area
276 : in text mode, we get with the second click eHit =
277 : SDRHIT_TEXTEDITOBJ since it goes to the TextObject which was
278 : created with the first click. But this is removed by
279 : SdrEndTextEdit since it is empty. But it is still in the mark
280 : list. The call MarkObj further below accesses then the dead
281 : object. As a simple fix, we determine eHit after
282 : SdrEndTextEdit again, this returns then SDRHIT_NONE. */
283 0 : mxTextObj.reset( NULL );
284 0 : eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
285 : }
286 :
287 0 : mpView->SetCurrentObj(OBJ_TEXT);
288 0 : mpView->SetEditMode(SDREDITMODE_EDIT);
289 : }
290 :
291 0 : if (rMEvt.IsLeft() || rMEvt.IsRight())
292 : {
293 0 : mpWindow->CaptureMouse();
294 0 : SdrPageView* pPV = mpView->GetSdrPageView();
295 :
296 0 : if (eHit == SDRHIT_TEXTEDIT)
297 : {
298 0 : SetInEditMode(rMEvt, false);
299 : }
300 : else
301 : {
302 0 : if (eHit != SDRHIT_HANDLE)
303 : {
304 : // deselect selection
305 0 : if (!rMEvt.IsShift() && eHit == SDRHIT_TEXTEDITOBJ)
306 : {
307 0 : mpView->UnmarkAll();
308 0 : mpView->SetDragMode(SDRDRAG_MOVE);
309 : }
310 : }
311 :
312 0 : if ( aVEvt.eEvent == SDREVENT_EXECUTEURL ||
313 0 : eHit == SDRHIT_HANDLE ||
314 0 : eHit == SDRHIT_MARKEDOBJECT ||
315 0 : eHit == SDRHIT_TEXTEDITOBJ ||
316 0 : ( eHit == SDRHIT_UNMARKEDOBJECT && bFirstObjCreated &&
317 0 : !bPermanent ) )
318 : {
319 : // Handle, hit marked or umarked object
320 0 : if (eHit == SDRHIT_TEXTEDITOBJ)
321 : {
322 : /* hit text of unmarked object:
323 : select object and set to EditMode */
324 0 : mpView->MarkObj(aVEvt.pRootObj, pPV);
325 :
326 0 : if (aVEvt.pObj && aVEvt.pObj->ISA(SdrTextObj))
327 : {
328 0 : mxTextObj.reset( static_cast<SdrTextObj*>(aVEvt.pObj) );
329 : }
330 :
331 0 : SetInEditMode(rMEvt, true);
332 : }
333 0 : else if (aVEvt.eEvent == SDREVENT_EXECUTEURL && !rMEvt.IsMod2())
334 : {
335 : // execute URL
336 0 : mpWindow->ReleaseMouse();
337 0 : SfxStringItem aStrItem(SID_FILE_NAME, aVEvt.pURLField->GetURL());
338 0 : SfxStringItem aReferer(SID_REFERER, mpDocSh->GetMedium()->GetName());
339 0 : SfxBoolItem aBrowseItem( SID_BROWSE, true );
340 0 : SfxViewFrame* pFrame = mpViewShell->GetViewFrame();
341 0 : mpWindow->ReleaseMouse();
342 :
343 0 : if (rMEvt.IsMod1())
344 : {
345 : // open in new frame
346 : pFrame->GetDispatcher()->Execute(SID_OPENDOC, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
347 0 : &aStrItem, &aBrowseItem, &aReferer, 0L);
348 : }
349 : else
350 : {
351 : // open in current frame
352 0 : SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame);
353 : pFrame->GetDispatcher()->Execute(SID_OPENDOC, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
354 0 : &aStrItem, &aFrameItem, &aBrowseItem, &aReferer, 0L);
355 0 : }
356 : }
357 : else
358 : {
359 : // drag object or handle
360 :
361 : // #i78748#
362 : // do the EndTextEdit first, it will delete the handles and force a
363 : // recreation. This will make aVEvt.pHdl to point to a deleted handle,
364 : // thus it is necessary to reset it and to get it again.
365 :
366 : // #i112855#
367 : // cl: I'm not sure why we checked here also for mxTextObj->GetOutlinerParaObjet
368 : // this caused SdrEndTextEdit() to be called also when not in text editing and
369 : // this does not make sense and caused troubles. (see issue 112855)
370 :
371 0 : if( mpView->IsTextEdit() )
372 : {
373 0 : mpView->SdrEndTextEdit();
374 0 : bJustEndedEdit = true;
375 :
376 0 : if(aVEvt.pHdl)
377 : {
378 : // force new handle identification, the pointer will be dead here
379 : // since SdrEndTextEdit has resetted (deleted) the handles.
380 0 : aVEvt.pHdl = 0;
381 0 : mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
382 : }
383 : }
384 :
385 0 : if (!aVEvt.pHdl)
386 : {
387 0 : if( eHit == SDRHIT_UNMARKEDOBJECT )
388 : {
389 0 : if ( !rMEvt.IsShift() )
390 0 : mpView->UnmarkAll();
391 :
392 0 : mpView->MarkObj(aVEvt.pRootObj, pPV);
393 : }
394 :
395 : // Drag object
396 0 : bFirstMouseMove = true;
397 0 : aDragTimer.Start();
398 : }
399 :
400 0 : if ( ! rMEvt.IsRight())
401 : {
402 : // we need to pick again since SdrEndTextEdit can rebuild the handles list
403 0 : eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
404 0 : if( (eHit == SDRHIT_HANDLE) || (eHit == SDRHIT_MARKEDOBJECT) )
405 : {
406 0 : sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
407 0 : mpView->BegDragObj(aMDPos, nullptr, aVEvt.pHdl, nDrgLog);
408 : }
409 : }
410 0 : bReturn = true;
411 0 : }
412 : }
413 0 : else if ( nSlotId != SID_TEXTEDIT &&
414 0 : (bPermanent || !bFirstObjCreated) )
415 : {
416 : // create object
417 0 : mpView->SetCurrentObj(OBJ_TEXT);
418 0 : mpView->SetEditMode(SDREDITMODE_CREATE);
419 0 : sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
420 0 : mpView->BegCreateObj(aMDPos, nullptr, nDrgLog);
421 : }
422 : else
423 : {
424 : // select
425 0 : if( !rMEvt.IsShift() )
426 0 : mpView->UnmarkAll();
427 :
428 0 : mpView->BegMarkObj( aMDPos );
429 : }
430 : }
431 : }
432 : }
433 0 : else if ( rMEvt.GetClicks() == 2 && !mpView->IsTextEdit() )
434 : {
435 0 : MouseEvent aMEvt( mpWindow->GetPointerPosPixel() );
436 0 : SetInEditMode( aMEvt, false );
437 : }
438 :
439 0 : if (!bIsInDragMode)
440 : {
441 0 : ForcePointer(&rMEvt);
442 0 : mpViewShell->GetViewFrame()->GetBindings().Invalidate(SidArray);
443 : }
444 :
445 0 : return bReturn;
446 : }
447 :
448 0 : bool FuText::MouseMove(const MouseEvent& rMEvt)
449 : {
450 0 : bool bReturn = FuDraw::MouseMove(rMEvt);
451 :
452 0 : if (aDragTimer.IsActive() )
453 : {
454 0 : if( bFirstMouseMove )
455 0 : bFirstMouseMove = false;
456 : else
457 0 : aDragTimer.Stop();
458 : }
459 :
460 0 : if (!bReturn && mpView->IsAction() && !mpDocSh->IsReadOnly())
461 : {
462 0 : Point aPix(rMEvt.GetPosPixel());
463 0 : Point aPnt(mpWindow->PixelToLogic(aPix));
464 :
465 0 : ForceScroll(aPix);
466 0 : mpView->MovAction(aPnt);
467 : }
468 :
469 0 : ForcePointer(&rMEvt);
470 :
471 0 : return bReturn;
472 : }
473 :
474 0 : void FuText::ImpSetAttributesForNewTextObject(SdrTextObj* pTxtObj)
475 : {
476 0 : if(mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS)
477 : {
478 0 : if( nSlotId == SID_ATTR_CHAR )
479 : {
480 : /* Create Impress text object (rescales to line height)
481 : We get the correct height during the subsequent creation of the
482 : object, otherwise we draw to much */
483 0 : SfxItemSet aSet(mpViewShell->GetPool());
484 0 : aSet.Put(makeSdrTextMinFrameHeightItem(0));
485 0 : aSet.Put(makeSdrTextAutoGrowWidthItem(false));
486 0 : aSet.Put(makeSdrTextAutoGrowHeightItem(true));
487 0 : pTxtObj->SetMergedItemSet(aSet);
488 0 : pTxtObj->AdjustTextFrameWidthAndHeight();
489 0 : aSet.Put(makeSdrTextMaxFrameHeightItem(pTxtObj->GetLogicRect().GetSize().Height()));
490 0 : pTxtObj->SetMergedItemSet(aSet);
491 : }
492 0 : else if( nSlotId == SID_ATTR_CHAR_VERTICAL )
493 : {
494 0 : SfxItemSet aSet(mpViewShell->GetPool());
495 0 : aSet.Put(makeSdrTextMinFrameWidthItem(0));
496 0 : aSet.Put(makeSdrTextAutoGrowWidthItem(true));
497 0 : aSet.Put(makeSdrTextAutoGrowHeightItem(false));
498 :
499 : // Needs to be set since default is SDRTEXTHORZADJUST_BLOCK
500 0 : aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
501 0 : pTxtObj->SetMergedItemSet(aSet);
502 0 : pTxtObj->AdjustTextFrameWidthAndHeight();
503 0 : aSet.Put(makeSdrTextMaxFrameWidthItem(pTxtObj->GetLogicRect().GetSize().Width()));
504 0 : pTxtObj->SetMergedItemSet(aSet);
505 : }
506 : }
507 : else
508 : {
509 0 : if( nSlotId == SID_ATTR_CHAR_VERTICAL )
510 : {
511 : // draw text object, needs to be initialized when vertical text is used
512 0 : SfxItemSet aSet(mpViewShell->GetPool());
513 :
514 0 : aSet.Put(makeSdrTextAutoGrowWidthItem(true));
515 0 : aSet.Put(makeSdrTextAutoGrowHeightItem(false));
516 :
517 : // Set defaults for vertical click-n'drag text object, pool defaults are:
518 : // SdrTextVertAdjustItem: SDRTEXTVERTADJUST_TOP
519 : // SdrTextHorzAdjustItem: SDRTEXTHORZADJUST_BLOCK
520 : // Analog to that:
521 0 : aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK));
522 0 : aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
523 :
524 0 : pTxtObj->SetMergedItemSet(aSet);
525 : }
526 : }
527 0 : }
528 :
529 0 : void FuText::ImpSetAttributesFitToSize(SdrTextObj* pTxtObj)
530 : {
531 : // FitToSize (fit to frame)
532 0 : SfxItemSet aSet(mpViewShell->GetPool(), SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWWIDTH);
533 0 : SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL;
534 0 : aSet.Put(SdrTextFitToSizeTypeItem(eFTS));
535 0 : aSet.Put(makeSdrTextAutoGrowHeightItem(false));
536 0 : aSet.Put(makeSdrTextAutoGrowWidthItem(false));
537 0 : pTxtObj->SetMergedItemSet(aSet);
538 0 : pTxtObj->AdjustTextFrameWidthAndHeight();
539 0 : }
540 :
541 0 : void FuText::ImpSetAttributesFitToSizeVertical(SdrTextObj* pTxtObj)
542 : {
543 0 : SfxItemSet aSet(mpViewShell->GetPool(),
544 0 : SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWWIDTH);
545 0 : SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL;
546 0 : aSet.Put(SdrTextFitToSizeTypeItem(eFTS));
547 0 : aSet.Put(makeSdrTextAutoGrowHeightItem(false));
548 0 : aSet.Put(makeSdrTextAutoGrowWidthItem(false));
549 0 : pTxtObj->SetMergedItemSet(aSet);
550 0 : pTxtObj->AdjustTextFrameWidthAndHeight();
551 0 : }
552 :
553 0 : void FuText::ImpSetAttributesFitCommon(SdrTextObj* pTxtObj)
554 : {
555 : // Normal Textobject
556 0 : if (mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS)
557 : {
558 0 : if( nSlotId == SID_ATTR_CHAR )
559 : {
560 : // Impress text object (rescales to line height)
561 0 : SfxItemSet aSet(mpViewShell->GetPool());
562 0 : aSet.Put(makeSdrTextMinFrameHeightItem(0));
563 0 : aSet.Put(makeSdrTextMaxFrameHeightItem(0));
564 0 : aSet.Put(makeSdrTextAutoGrowHeightItem(true));
565 0 : aSet.Put(makeSdrTextAutoGrowWidthItem(false));
566 0 : pTxtObj->SetMergedItemSet(aSet);
567 : }
568 0 : else if( nSlotId == SID_ATTR_CHAR_VERTICAL )
569 : {
570 0 : SfxItemSet aSet(mpViewShell->GetPool());
571 0 : aSet.Put(makeSdrTextMinFrameWidthItem(0));
572 0 : aSet.Put(makeSdrTextMaxFrameWidthItem(0));
573 0 : aSet.Put(makeSdrTextAutoGrowWidthItem(true));
574 0 : aSet.Put(makeSdrTextAutoGrowHeightItem(false));
575 0 : pTxtObj->SetMergedItemSet(aSet);
576 : }
577 :
578 0 : pTxtObj->AdjustTextFrameWidthAndHeight();
579 : }
580 0 : }
581 :
582 1 : bool FuText::MouseButtonUp(const MouseEvent& rMEvt)
583 : {
584 1 : bool bReturn = false;
585 : SdrObject* pObj;
586 : SdrPageView* pPV;
587 1 : if (aDragTimer.IsActive())
588 : {
589 0 : aDragTimer.Stop();
590 0 : bIsInDragMode = false;
591 : }
592 :
593 1 : mpViewShell->GetViewFrame()->GetBindings().Invalidate( SidArray );
594 :
595 1 : Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
596 :
597 1 : if( (mpView && mpView->MouseButtonUp(rMEvt, mpWindow)) || rMEvt.GetClicks() == 2 )
598 1 : return true; // handle event from SdrView
599 :
600 0 : bool bEmptyTextObj = false;
601 :
602 0 : if (mxTextObj.is())
603 : {
604 0 : bool bReset = true;
605 :
606 0 : if (mpView)
607 : {
608 0 : const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
609 :
610 0 : if (rMarkList.GetMarkCount() == 1
611 0 : && ( rMarkList.GetMark(0)->GetMarkedSdrObj() == mxTextObj.get()) )
612 : {
613 0 : if( mxTextObj.is() && !GetTextObj()->GetOutlinerParaObject() )
614 0 : bEmptyTextObj = true;
615 : else
616 0 : bFirstObjCreated = true;
617 0 : bReset = false;
618 : }
619 : }
620 :
621 0 : if (bReset)
622 : {
623 0 : mxTextObj.reset( 0 );
624 : }
625 : }
626 :
627 0 : if( mpView && mpView->IsDragObj())
628 : {
629 : // object was moved
630 0 : FrameView* pFrameView = mpViewShell->GetFrameView();
631 0 : bool bDragWithCopy = (rMEvt.IsMod1() && pFrameView->IsDragWithCopy());
632 :
633 0 : if (bDragWithCopy)
634 : {
635 0 : bDragWithCopy = !mpView->IsPresObjSelected(false, true);
636 : }
637 :
638 0 : mpView->SetDragWithCopy(bDragWithCopy);
639 0 : mpView->EndDragObj( mpView->IsDragWithCopy() );
640 0 : mpView->ForceMarkedToAnotherPage();
641 0 : mpView->SetCurrentObj(OBJ_TEXT);
642 :
643 0 : sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
644 :
645 0 : if (bJustEndedEdit)
646 : {
647 0 : bJustEndedEdit = false;
648 0 : FuPoor::cancel();
649 : }
650 0 : if ((rMEvt.GetClicks() != 2) &&
651 0 : !rMEvt.IsShift() && !rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsRight() &&
652 0 : std::abs(aPnt.X() - aMDPos.X()) < nDrgLog &&
653 0 : std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog)
654 : {
655 : /*************************************************************
656 : * From text mode, you don't want to rotate immediately.
657 : **************************************************************/
658 0 : if (mpView->PickObj(aMDPos, mpView->getHitTolLog(), pObj, pPV, SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::BEFOREMARK))
659 : {
660 0 : mpView->UnmarkAllObj();
661 0 : mpView->MarkObj(pObj,pPV,false,false);
662 0 : return bReturn;
663 : }
664 : }
665 : }
666 0 : else if( mpView && mpView->IsCreateObj() && rMEvt.IsLeft())
667 : {
668 : // object was created
669 0 : mxTextObj.reset( dynamic_cast< SdrTextObj* >( mpView->GetCreateObj() ) );
670 :
671 0 : if( mxTextObj.is() )
672 : {
673 : //AW outliner needs to be set to vertical when there is no
674 : // outliner object up to now; also it needs to be set back to not
675 : // vertical when there was a vertical one used last time.
676 0 : OutlinerParaObject* pOPO = GetTextObj()->GetOutlinerParaObject();
677 0 : SdrOutliner& rOutl = mxTextObj->GetModel()->GetDrawOutliner(GetTextObj());
678 0 : bool bVertical((pOPO && pOPO->IsVertical())
679 0 : || nSlotId == SID_ATTR_CHAR_VERTICAL
680 0 : || nSlotId == SID_TEXT_FITTOSIZE_VERTICAL);
681 0 : rOutl.SetVertical(bVertical);
682 :
683 : // Before ImpSetAttributesForNewTextObject the vertical writing mode
684 : // needs to be set at the object. This is done here at the OutlinerParaObject
685 : // directly to not mirror the layout text items involved. These items will be set
686 : // from ImpSetAttributesForNewTextObject and below.
687 0 : OutlinerParaObject* pPara = GetTextObj()->GetOutlinerParaObject();
688 :
689 0 : if(!pPara)
690 : {
691 0 : GetTextObj()->ForceOutlinerParaObject();
692 0 : pPara = GetTextObj()->GetOutlinerParaObject();
693 : }
694 :
695 0 : if(pPara && (bool)bVertical != pPara->IsVertical())
696 : {
697 : // set ParaObject orientation accordingly
698 0 : pPara->SetVertical(bVertical);
699 : }
700 :
701 0 : ImpSetAttributesForNewTextObject(GetTextObj());
702 : }
703 :
704 0 : if (!mpView->EndCreateObj(SDRCREATE_FORCEEND))
705 : {
706 : // it was not possible to create text object
707 0 : mxTextObj.reset(0);
708 : }
709 0 : else if (nSlotId == SID_TEXT_FITTOSIZE)
710 : {
711 0 : ImpSetAttributesFitToSize(GetTextObj());
712 :
713 0 : SetInEditMode(rMEvt, false);
714 : }
715 0 : else if ( nSlotId == SID_TEXT_FITTOSIZE_VERTICAL )
716 : {
717 0 : ImpSetAttributesFitToSizeVertical(GetTextObj());
718 :
719 0 : SetInEditMode(rMEvt, false);
720 : }
721 : else
722 : {
723 0 : ImpSetAttributesFitCommon(GetTextObj());
724 :
725 : // thereby the handles and the gray frame are correct
726 0 : mpView->AdjustMarkHdl();
727 0 : mpView->PickHandle(aPnt);
728 0 : SetInEditMode(rMEvt, false);
729 : }
730 : }
731 0 : else if ( mpView && mpView->IsAction())
732 : {
733 0 : mpView->EndAction();
734 : }
735 :
736 0 : ForcePointer(&rMEvt);
737 0 : mpWindow->ReleaseMouse();
738 0 : sal_uInt16 nDrgLog1 = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
739 :
740 0 : if ( mpView && !mpView->AreObjectsMarked() &&
741 0 : std::abs(aMDPos.X() - aPnt.X()) < nDrgLog1 &&
742 0 : std::abs(aMDPos.Y() - aPnt.Y()) < nDrgLog1 &&
743 0 : !rMEvt.IsShift() && !rMEvt.IsMod2() )
744 : {
745 0 : SdrPageView* pPV2 = mpView->GetSdrPageView();
746 0 : SdrViewEvent aVEvt;
747 0 : mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
748 0 : mpView->MarkObj(aVEvt.pRootObj, pPV2);
749 : }
750 :
751 0 : if ( !mxTextObj.is() && mpView )
752 : {
753 0 : if ( ( (!bEmptyTextObj && bPermanent) ||
754 0 : (!bFirstObjCreated && !bPermanent) ) &&
755 0 : !mpDocSh->IsReadOnly() &&
756 0 : nSlotId != SID_TEXTEDIT )
757 : {
758 : // text body (left-justified AutoGrow)
759 0 : mpView->SetCurrentObj(OBJ_TEXT);
760 0 : mpView->SetEditMode(SDREDITMODE_CREATE);
761 0 : sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
762 0 : mpView->BegCreateObj(aMDPos, nullptr, nDrgLog);
763 :
764 0 : bool bSnapEnabled = mpView->IsSnapEnabled();
765 :
766 0 : if (bSnapEnabled)
767 0 : mpView->SetSnapEnabled(false);
768 :
769 0 : aPnt.X() += nDrgLog + nDrgLog;
770 0 : aPnt.Y() += nDrgLog + nDrgLog;
771 0 : mpView->MovAction(aPnt);
772 :
773 0 : mxTextObj.reset( dynamic_cast< SdrTextObj* >( mpView->GetCreateObj() ) );
774 :
775 0 : if(mxTextObj.is())
776 : {
777 0 : GetTextObj()->SetDisableAutoWidthOnDragging(true);
778 : }
779 :
780 0 : if(!mpView->EndCreateObj(SDRCREATE_FORCEEND))
781 : {
782 0 : mxTextObj.reset(0);
783 : }
784 :
785 0 : if(bSnapEnabled)
786 0 : mpView->SetSnapEnabled(bSnapEnabled);
787 :
788 0 : if(mxTextObj.is())
789 : {
790 0 : SfxItemSet aSet(mpViewShell->GetPool());
791 0 : aSet.Put(makeSdrTextMinFrameHeightItem(0));
792 0 : aSet.Put(makeSdrTextMinFrameWidthItem(0));
793 0 : aSet.Put(makeSdrTextAutoGrowHeightItem(true));
794 0 : aSet.Put(makeSdrTextAutoGrowWidthItem(true));
795 :
796 0 : if(nSlotId == SID_ATTR_CHAR_VERTICAL)
797 : {
798 : // Here, all items which need to be different from pool default need to be set
799 : // again on the newly created text object.
800 : // Since this is a simple click text object, it is first created, then SetVertical()
801 : // is used, then ImpSetAttributesForNewTextObject is called and then the object is
802 : // deleted again since not the minimum drag distance was travelled. Then, a new
803 : // click text object is created and thus all that stuff needs to be set again here.
804 :
805 : // Before using the new object the vertical writing mode
806 : // needs to be set. This is done here at the OutlinerParaObject
807 : // directly to not mirror the layout text items involved. These items will be set
808 : // below.
809 0 : OutlinerParaObject* pPara = GetTextObj()->GetOutlinerParaObject();
810 :
811 0 : if(!pPara)
812 : {
813 0 : GetTextObj()->ForceOutlinerParaObject();
814 0 : pPara = GetTextObj()->GetOutlinerParaObject();
815 : }
816 :
817 0 : if(pPara && !pPara->IsVertical())
818 : {
819 : // set ParaObject orientation accordingly
820 0 : pPara->SetVertical(true);
821 : }
822 :
823 0 : aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
824 :
825 : // Analog to the else case below, for vertical simple click texts
826 : // one of the defaulted setted items from ImpSetAttributesForNewTextObject
827 : // needs to be adapted to non-block mode.
828 0 : const SfxItemSet& rSet = mpView->GetDefaultAttr();
829 0 : SvxFrameDirection eDirection = (SvxFrameDirection)static_cast<const SvxFrameDirectionItem&>(rSet.Get(EE_PARA_WRITINGDIR)).GetValue();
830 :
831 0 : if(FRMDIR_HORI_RIGHT_TOP == eDirection || FRMDIR_VERT_TOP_RIGHT == eDirection)
832 : {
833 0 : aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM));
834 : }
835 : else
836 : {
837 0 : aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP));
838 : }
839 : }
840 : else
841 : {
842 : // This is for Format/Page settings. Since this also leads
843 : // to the object defaults to be changed, i think this code can be
844 : // removed. CL. wanted to take a look before adding this.
845 :
846 : // Look in the object defaults if left-to-right is wanted. If
847 : // yes, set text anchoring to right to let the box grow to left.
848 0 : const SfxItemSet& rSet = mpView->GetDefaultAttr();
849 0 : SvxFrameDirection eDirection = (SvxFrameDirection)static_cast<const SvxFrameDirectionItem&>(rSet.Get(EE_PARA_WRITINGDIR)).GetValue();
850 :
851 0 : if(FRMDIR_HORI_RIGHT_TOP == eDirection)
852 : {
853 0 : aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
854 : }
855 : else
856 : {
857 0 : aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT));
858 : }
859 : }
860 :
861 0 : GetTextObj()->SetMergedItemSet(aSet);
862 0 : GetTextObj()->SetDisableAutoWidthOnDragging(true);
863 0 : SetInEditMode(rMEvt, false);
864 : }
865 :
866 0 : bFirstObjCreated = true;
867 : }
868 : else
869 : {
870 : // switch to selection
871 0 : if (mpView->SdrEndTextEdit() == SDRENDTEXTEDIT_DELETED)
872 : {
873 0 : mxTextObj.reset(0);
874 : }
875 :
876 : mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_OBJECT_SELECT,
877 0 : SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
878 : }
879 : }
880 0 : if (bJustEndedEdit)
881 : {
882 0 : bJustEndedEdit = false;
883 0 : FuPoor::cancel();
884 : }
885 0 : bMBDown = false;
886 0 : FuConstruct::MouseButtonUp(rMEvt);
887 0 : return bReturn;
888 : }
889 :
890 : /**
891 : * handle keyboard events
892 : * @returns sal_True if the event was handled, sal_False otherwise
893 : */
894 1 : bool FuText::KeyInput(const KeyEvent& rKEvt)
895 : {
896 1 : bool bReturn = false;
897 1 : mpView->SetMarkHdlWhenTextEdit(true);
898 :
899 1 : vcl::KeyCode nCode = rKEvt.GetKeyCode();
900 1 : bool bShift = nCode.IsShift();
901 :
902 1 : if(mxTextObj.is())
903 : {
904 : // maybe object is deleted, test if it's equal to the selected object
905 1 : const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
906 1 : SdrObject* pSelectedObj = 0L;
907 :
908 1 : if(1 == rMarkList.GetMarkCount())
909 : {
910 1 : SdrMark* pMark = rMarkList.GetMark(0);
911 1 : pSelectedObj = pMark->GetMarkedSdrObj();
912 : }
913 :
914 1 : if(mxTextObj.get() != pSelectedObj)
915 : {
916 0 : mxTextObj.reset(0);
917 : }
918 : }
919 :
920 1 : if ( mxTextObj.is() && mxTextObj->GetObjInventor() == SdrInventor && mxTextObj->GetObjIdentifier() == OBJ_TITLETEXT && rKEvt.GetKeyCode().GetCode() == KEY_RETURN )
921 : {
922 : // title text object: always soft breaks
923 0 : bShift = true;
924 : }
925 :
926 1 : sal_uInt16 nKey = nCode.GetCode();
927 1 : vcl::KeyCode aKeyCode (nKey, bShift, nCode.IsMod1(), nCode.IsMod2(), nCode.IsMod3() );
928 1 : KeyEvent aKEvt(rKEvt.GetCharCode(), aKeyCode);
929 :
930 1 : bool bOK = true;
931 :
932 1 : if (mpDocSh->IsReadOnly())
933 : {
934 0 : bOK = !EditEngine::DoesKeyChangeText(aKEvt);
935 : }
936 1 : if( aKeyCode.GetCode() == KEY_PAGEUP || aKeyCode.GetCode() == KEY_PAGEDOWN )
937 : {
938 0 : bOK = false; // default handling in base class
939 : }
940 :
941 1 : if (bOK && mpView->KeyInput(aKEvt, mpWindow) )
942 : {
943 1 : bReturn = true;
944 :
945 1 : mpViewShell->GetViewFrame()->GetBindings().Invalidate( SidArray );
946 :
947 : }
948 0 : else if (aKeyCode == KEY_ESCAPE)
949 : {
950 0 : bReturn = cancel();
951 : }
952 :
953 1 : if( bPermanent )
954 : {
955 0 : mpView->SetCurrentObj(OBJ_TEXT);
956 0 : mpView->SetEditMode(SDREDITMODE_CREATE);
957 : }
958 :
959 1 : if (!bReturn)
960 : {
961 0 : bReturn = FuDraw::KeyInput(aKEvt);
962 : }
963 :
964 1 : return bReturn;
965 : }
966 :
967 3 : void FuText::Activate()
968 : {
969 3 : mpView->SetQuickTextEditMode(mpViewShell->GetFrameView()->IsQuickEdit());
970 :
971 : // #i89661# it's no longer necessary to make it so big here, it's fine tuned
972 : // for text objects in SdrMarkView::CheckSingleSdrObjectHit
973 3 : mpView->SetHitTolerancePixel( 2 * HITPIX );
974 :
975 3 : OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
976 :
977 3 : if (pOLV)
978 2 : pOLV->ShowCursor();
979 :
980 3 : FuConstruct::Activate();
981 :
982 3 : if( pOLV )
983 2 : mpView->SetEditMode(SDREDITMODE_EDIT);
984 3 : }
985 :
986 6 : void FuText::Deactivate()
987 : {
988 6 : OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
989 :
990 6 : if (pOLV)
991 0 : pOLV->HideCursor();
992 :
993 6 : mpView->SetHitTolerancePixel( HITPIX );
994 :
995 6 : FuConstruct::Deactivate();
996 6 : }
997 :
998 : /**
999 : * Sets the object into the edit mode.
1000 : */
1001 4 : void FuText::SetInEditMode(const MouseEvent& rMEvt, bool bQuickDrag)
1002 : {
1003 4 : SdrPageView* pPV = mpView->GetSdrPageView();
1004 4 : if( mxTextObj.is() && (mxTextObj->GetPage() == pPV->GetPage()) )
1005 : {
1006 2 : mpView->SetCurrentObj(OBJ_TEXT);
1007 :
1008 2 : if( bPermanent )
1009 0 : mpView->SetEditMode(SDREDITMODE_CREATE);
1010 : else
1011 2 : mpView->SetEditMode(SDREDITMODE_EDIT);
1012 :
1013 2 : bool bEmptyOutliner = false;
1014 :
1015 2 : if (!GetTextObj()->GetOutlinerParaObject() && mpView->GetTextEditOutliner())
1016 : {
1017 0 : ::Outliner* pOutl = mpView->GetTextEditOutliner();
1018 0 : sal_Int32 nParaAnz = pOutl->GetParagraphCount();
1019 0 : Paragraph* p1stPara = pOutl->GetParagraph( 0 );
1020 :
1021 0 : if (nParaAnz==1 && p1stPara)
1022 : {
1023 : // with only one paragraph
1024 0 : if (pOutl->GetText(p1stPara).isEmpty())
1025 : {
1026 0 : bEmptyOutliner = true;
1027 : }
1028 : }
1029 : }
1030 :
1031 2 : if (GetTextObj() != mpView->GetTextEditObject() || bEmptyOutliner)
1032 : {
1033 2 : sal_uInt32 nInv = mxTextObj->GetObjInventor();
1034 2 : sal_uInt16 nSdrObjKind = mxTextObj->GetObjIdentifier();
1035 :
1036 4 : if (nInv == SdrInventor && GetTextObj()->HasTextEdit() &&
1037 2 : (nSdrObjKind == OBJ_TEXT ||
1038 0 : nSdrObjKind == OBJ_TITLETEXT ||
1039 0 : nSdrObjKind == OBJ_OUTLINETEXT || !mxTextObj->IsEmptyPresObj() ) )
1040 : {
1041 : // create new outliner (owned by SdrObjEditView)
1042 2 : SdrOutliner* pOutl = SdrMakeOutliner(OUTLINERMODE_OUTLINEOBJECT, *mpDoc);
1043 :
1044 2 : if (bEmptyOutliner)
1045 0 : mpView->SdrEndTextEdit(true);
1046 :
1047 2 : SdrTextObj* pTextObj = GetTextObj();
1048 2 : if( pTextObj )
1049 : {
1050 2 : OutlinerParaObject* pOPO = pTextObj->GetOutlinerParaObject();
1051 2 : if( ( pOPO && pOPO->IsVertical() ) || (nSlotId == SID_ATTR_CHAR_VERTICAL) || (nSlotId == SID_TEXT_FITTOSIZE_VERTICAL) )
1052 0 : pOutl->SetVertical( true );
1053 :
1054 2 : if( pTextObj->getTextCount() > 1 )
1055 : {
1056 0 : Point aPix(rMEvt.GetPosPixel());
1057 0 : Point aPnt(mpWindow->PixelToLogic(aPix));
1058 0 : pTextObj->setActiveText( pTextObj->CheckTextHit(aPnt ) );
1059 : }
1060 :
1061 2 : if (mpView->SdrBeginTextEdit(pTextObj, pPV, mpWindow, true, pOutl) && mxTextObj->GetObjInventor() == SdrInventor)
1062 : {
1063 2 : bFirstObjCreated = true;
1064 2 : DeleteDefaultText();
1065 :
1066 2 : OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
1067 :
1068 2 : nSdrObjKind = mxTextObj->GetObjIdentifier();
1069 :
1070 2 : SdrViewEvent aVEvt;
1071 2 : SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
1072 :
1073 2 : if (eHit == SDRHIT_TEXTEDIT)
1074 : {
1075 : // hit text
1076 0 : if (nSdrObjKind == OBJ_TEXT ||
1077 0 : nSdrObjKind == OBJ_TITLETEXT ||
1078 0 : nSdrObjKind == OBJ_OUTLINETEXT ||
1079 0 : nSdrObjKind == OBJ_TABLE ||
1080 0 : nSlotId == SID_TEXTEDIT ||
1081 0 : !bQuickDrag)
1082 : {
1083 0 : pOLV->MouseButtonDown(rMEvt);
1084 0 : pOLV->MouseMove(rMEvt);
1085 0 : pOLV->MouseButtonUp(rMEvt);
1086 : }
1087 :
1088 0 : if (mpViewShell->GetFrameView()->IsQuickEdit() && bQuickDrag && GetTextObj()->GetOutlinerParaObject())
1089 : {
1090 0 : pOLV->MouseButtonDown(rMEvt);
1091 : }
1092 : }
1093 : else
1094 : {
1095 : // Move cursor to end of text
1096 2 : ESelection aNewSelection(EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND, EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND);
1097 2 : if (pOLV != NULL)
1098 2 : pOLV->SetSelection(aNewSelection);
1099 2 : }
1100 : }
1101 : else
1102 : {
1103 0 : mpView->RestoreDefaultText(dynamic_cast< SdrTextObj* >( mxTextObj.get() ));
1104 : }
1105 : }
1106 : }
1107 : }
1108 : }
1109 : else
1110 : {
1111 2 : mxTextObj.reset(0);
1112 : }
1113 4 : }
1114 :
1115 : /**
1116 : * Text entry is started, if necessary delete the default text.
1117 : */
1118 2 : bool FuText::DeleteDefaultText()
1119 : {
1120 2 : bool bDeleted = false;
1121 :
1122 2 : if ( mxTextObj.is() && mxTextObj->IsEmptyPresObj() )
1123 : {
1124 2 : SdPage* pPage = static_cast<SdPage*>( mxTextObj->GetPage() );
1125 :
1126 2 : if (pPage)
1127 : {
1128 2 : PresObjKind ePresObjKind = pPage->GetPresObjKind(mxTextObj.get());
1129 :
1130 2 : if ( (ePresObjKind == PRESOBJ_TITLE ||
1131 0 : ePresObjKind == PRESOBJ_OUTLINE ||
1132 0 : ePresObjKind == PRESOBJ_NOTES ||
1133 4 : ePresObjKind == PRESOBJ_TEXT) &&
1134 2 : !pPage->IsMasterPage() )
1135 : {
1136 2 : ::Outliner* pOutliner = mpView->GetTextEditOutliner();
1137 2 : SfxStyleSheet* pSheet = pOutliner->GetStyleSheet( 0 );
1138 2 : bool bIsUndoEnabled = pOutliner->IsUndoEnabled();
1139 2 : if( bIsUndoEnabled )
1140 2 : pOutliner->EnableUndo(false);
1141 :
1142 2 : pOutliner->SetText( OUString(), pOutliner->GetParagraph( 0 ) );
1143 :
1144 2 : if( bIsUndoEnabled )
1145 2 : pOutliner->EnableUndo(true);
1146 :
1147 2 : if (pSheet &&
1148 2 : (ePresObjKind == PRESOBJ_NOTES || ePresObjKind == PRESOBJ_TEXT))
1149 0 : pOutliner->SetStyleSheet(0, pSheet);
1150 :
1151 2 : mxTextObj->SetEmptyPresObj(true);
1152 2 : bDeleted = true;
1153 : }
1154 : }
1155 : }
1156 :
1157 2 : return bDeleted;
1158 : }
1159 :
1160 0 : bool FuText::Command(const CommandEvent& rCEvt)
1161 : {
1162 0 : return FuPoor::Command(rCEvt);
1163 : }
1164 :
1165 0 : bool FuText::RequestHelp(const HelpEvent& rHEvt)
1166 : {
1167 0 : bool bReturn = false;
1168 :
1169 0 : OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
1170 :
1171 0 : if ((Help::IsBalloonHelpEnabled() || Help::IsQuickHelpEnabled()) &&
1172 0 : mxTextObj.is() && pOLV && pOLV->GetFieldUnderMousePointer())
1173 : {
1174 0 : OUString aHelpText;
1175 0 : const SvxFieldItem* pFieldItem = pOLV->GetFieldUnderMousePointer();
1176 0 : const SvxFieldData* pField = pFieldItem->GetField();
1177 :
1178 0 : if (pField && pField->ISA(SvxURLField))
1179 : {
1180 : // URL-Field
1181 0 : aHelpText = INetURLObject::decode( static_cast<const SvxURLField*>(pField)->GetURL(), INetURLObject::DECODE_WITH_CHARSET );
1182 : }
1183 0 : if (!aHelpText.isEmpty())
1184 : {
1185 0 : Rectangle aLogicPix = mpWindow->LogicToPixel(mxTextObj->GetLogicRect());
1186 0 : Rectangle aScreenRect(mpWindow->OutputToScreenPixel(aLogicPix.TopLeft()),
1187 0 : mpWindow->OutputToScreenPixel(aLogicPix.BottomRight()));
1188 :
1189 0 : if (Help::IsBalloonHelpEnabled())
1190 : {
1191 0 : bReturn = Help::ShowBalloon( static_cast<vcl::Window*>(mpWindow), rHEvt.GetMousePosPixel(), aScreenRect, aHelpText);
1192 : }
1193 0 : else if (Help::IsQuickHelpEnabled())
1194 : {
1195 0 : bReturn = Help::ShowQuickHelp( static_cast<vcl::Window*>(mpWindow), aScreenRect, aHelpText);
1196 : }
1197 0 : }
1198 : }
1199 :
1200 0 : if (!bReturn)
1201 : {
1202 0 : bReturn = FuConstruct::RequestHelp(rHEvt);
1203 : }
1204 :
1205 0 : return bReturn;
1206 : }
1207 :
1208 1 : void FuText::ReceiveRequest(SfxRequest& rReq)
1209 : {
1210 1 : nSlotId = rReq.GetSlot();
1211 :
1212 : // then we call the base class (besides others, nSlotId is NOT set there)
1213 1 : FuPoor::ReceiveRequest(rReq);
1214 :
1215 1 : if (nSlotId == SID_TEXTEDIT || mpViewShell->GetFrameView()->IsQuickEdit() || SID_ATTR_CHAR == nSlotId)
1216 : {
1217 1 : MouseEvent aMEvt(mpWindow->GetPointerPosPixel());
1218 :
1219 1 : mxTextObj.reset(0);
1220 :
1221 1 : if (nSlotId == SID_TEXTEDIT)
1222 : {
1223 : // are we currently editing?
1224 1 : if(!bTestText)
1225 1 : mxTextObj.reset( dynamic_cast< SdrTextObj* >( mpView->GetTextEditObject() ) );
1226 :
1227 1 : if (!mxTextObj.is())
1228 : {
1229 : // Try to select an object
1230 1 : SdrPageView* pPV = mpView->GetSdrPageView();
1231 1 : SdrViewEvent aVEvt;
1232 1 : mpView->PickAnything(aMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
1233 1 : mpView->MarkObj(aVEvt.pRootObj, pPV);
1234 :
1235 1 : if (aVEvt.pObj && aVEvt.pObj->ISA(SdrTextObj))
1236 : {
1237 0 : mxTextObj.reset( static_cast< SdrTextObj* >( aVEvt.pObj ) );
1238 1 : }
1239 : }
1240 : }
1241 0 : else if (mpView->AreObjectsMarked())
1242 : {
1243 0 : const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
1244 :
1245 0 : if (rMarkList.GetMarkCount() == 1)
1246 : {
1247 0 : SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
1248 :
1249 0 : if (pObj->ISA(SdrTextObj))
1250 : {
1251 0 : mxTextObj.reset( static_cast< SdrTextObj* >( pObj ) );
1252 : }
1253 : }
1254 : }
1255 :
1256 1 : bool bQuickDrag = true;
1257 :
1258 1 : const SfxItemSet* pArgs = rReq.GetArgs();
1259 :
1260 1 : if (pArgs
1261 :
1262 : // test for type before using
1263 1 : && SID_TEXTEDIT == nSlotId
1264 1 : && SfxItemState::SET == pArgs->GetItemState(SID_TEXTEDIT)
1265 :
1266 2 : && (sal_uInt16) static_cast<const SfxUInt16Item&>( pArgs->Get(SID_TEXTEDIT)).GetValue() == 2)
1267 : {
1268 : // selection wit double click -> do not allow QuickDrag
1269 0 : bQuickDrag = false;
1270 : }
1271 :
1272 1 : SetInEditMode(aMEvt, bQuickDrag);
1273 : }
1274 1 : }
1275 :
1276 0 : void FuText::DoubleClick(const MouseEvent& )
1277 : {
1278 : // Nothing to do
1279 0 : }
1280 :
1281 : /** Removed the insertion of default text and putting a new text
1282 : object directly into edit mode.
1283 : */
1284 0 : SdrObject* FuText::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle)
1285 : {
1286 :
1287 : SdrObject* pObj = SdrObjFactory::MakeNewObject(
1288 0 : mpView->GetCurrentObjInventor(), mpView->GetCurrentObjIdentifier(),
1289 0 : 0L, mpDoc);
1290 :
1291 0 : if(pObj)
1292 : {
1293 0 : if(pObj->ISA(SdrTextObj))
1294 : {
1295 0 : SdrTextObj* pText = static_cast<SdrTextObj*>(pObj);
1296 0 : pText->SetLogicRect(rRectangle);
1297 :
1298 0 : bool bVertical = (SID_ATTR_CHAR_VERTICAL == nID || SID_TEXT_FITTOSIZE_VERTICAL == nID);
1299 0 : pText->SetVerticalWriting(bVertical);
1300 :
1301 0 : ImpSetAttributesForNewTextObject(pText);
1302 :
1303 0 : if (nSlotId == SID_TEXT_FITTOSIZE)
1304 : {
1305 0 : ImpSetAttributesFitToSize(pText);
1306 : }
1307 0 : else if ( nSlotId == SID_TEXT_FITTOSIZE_VERTICAL )
1308 : {
1309 0 : ImpSetAttributesFitToSizeVertical(pText);
1310 : }
1311 : else
1312 : {
1313 0 : ImpSetAttributesFitCommon(pText);
1314 : }
1315 :
1316 : // Put text object into edit mode.
1317 0 : SdrPageView* pPV = mpView->GetSdrPageView();
1318 0 : mpView->SdrBeginTextEdit(pText, pPV);
1319 : }
1320 : else
1321 : {
1322 : OSL_FAIL("Object is NO text object");
1323 : }
1324 : }
1325 :
1326 0 : return pObj;
1327 : }
1328 :
1329 : /** is called when the current function should be aborted. <p>
1330 : This is used when a function gets a KEY_ESCAPE but can also
1331 : be called directly.
1332 :
1333 : @returns true if a active function was aborted
1334 : */
1335 0 : bool FuText::cancel()
1336 : {
1337 0 : if ( mpView->IsTextEdit() )
1338 : {
1339 0 : if(mpView->SdrEndTextEdit() == SDRENDTEXTEDIT_DELETED)
1340 0 : mxTextObj.reset(0);
1341 :
1342 0 : mpView->SetCurrentObj(OBJ_TEXT);
1343 0 : mpView->SetEditMode(SDREDITMODE_EDIT);
1344 0 : return true;
1345 : }
1346 : else
1347 : {
1348 0 : return false;
1349 : }
1350 : }
1351 :
1352 0 : void FuText::ChangeFontSize( bool bGrow, OutlinerView* pOLV, const FontList* pFontList, ::sd::View* pView )
1353 : {
1354 0 : if( !pFontList || !pView )
1355 0 : return;
1356 :
1357 0 : if( pOLV )
1358 : {
1359 0 : pOLV->GetEditView().ChangeFontSize( bGrow, pFontList );
1360 : }
1361 : else
1362 : {
1363 :
1364 0 : const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
1365 0 : for( size_t nMark = 0; nMark < rMarkList.GetMarkCount(); ++nMark )
1366 : {
1367 0 : SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( rMarkList.GetMark(nMark)->GetMarkedSdrObj() );
1368 0 : if( pTextObj )
1369 : {
1370 0 : for( sal_Int32 nText = 0; nText < pTextObj->getTextCount(); nText++ )
1371 : {
1372 0 : pTextObj->setActiveText( nText );
1373 :
1374 : // Put text object into edit mode.
1375 0 : SdrPageView* pPV = pView->GetSdrPageView();
1376 0 : pView->SdrBeginTextEdit(pTextObj, pPV);
1377 :
1378 0 : pOLV = pView->GetTextEditOutlinerView();
1379 0 : if( pOLV )
1380 : {
1381 0 : EditEngine* pEditEngine = pOLV->GetEditView().GetEditEngine();
1382 0 : if( pEditEngine )
1383 : {
1384 0 : ESelection aSel;
1385 0 : aSel.nEndPara = pEditEngine->GetParagraphCount()-1;
1386 0 : aSel.nEndPos = pEditEngine->GetTextLen(aSel.nEndPara);
1387 0 : pOLV->SetSelection(aSel);
1388 : }
1389 :
1390 0 : ChangeFontSize( bGrow, pOLV, pFontList, pView );
1391 : }
1392 :
1393 0 : pView->SdrEndTextEdit();
1394 : }
1395 :
1396 0 : SfxItemSet aShapeSet( pTextObj->GetMergedItemSet() );
1397 0 : if( EditView::ChangeFontSize( bGrow, aShapeSet, pFontList ) )
1398 : {
1399 0 : pTextObj->SetObjectItemNoBroadcast( aShapeSet.Get( EE_CHAR_FONTHEIGHT ) );
1400 0 : pTextObj->SetObjectItemNoBroadcast( aShapeSet.Get( EE_CHAR_FONTHEIGHT_CJK ) );
1401 0 : pTextObj->SetObjectItemNoBroadcast( aShapeSet.Get( EE_CHAR_FONTHEIGHT_CTL ) );
1402 0 : }
1403 : }
1404 : }
1405 : }
1406 : }
1407 :
1408 66 : } // end of namespace sd
1409 :
1410 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|