1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
20 #include <starmath.hrc>
23 #include <vcl/commandevent.hxx>
24 #include <vcl/event.hxx>
25 #include <vcl/scrbar.hxx>
26 #include <vcl/settings.hxx>
28 #include <editeng/editview.hxx>
29 #include <editeng/editeng.hxx>
30 #include <sfx2/dispatch.hxx>
31 #include <sfx2/sfxsids.hrc>
32 #include <svl/stritem.hxx>
33 #include <sfx2/viewfrm.hxx>
34 #include <svx/AccessibleTextHelper.hxx>
35 #include <svtools/colorcfg.hxx>
36 #include <osl/diagnose.h>
41 #include <document.hxx>
42 #include "cfgitem.hxx"
43 #include "accessibility.hxx"
46 #define SCROLL_LINE 24
49 using namespace com::sun::star::accessibility
;
50 using namespace com::sun::star
;
53 void SmGetLeftSelectionPart(const ESelection
&rSel
,
54 sal_Int32
&nPara
, sal_uInt16
&nPos
)
55 // returns paragraph number and position of the selections left part
57 // compare start and end of selection and use the one that comes first
58 if ( rSel
.nStartPara
< rSel
.nEndPara
59 || (rSel
.nStartPara
== rSel
.nEndPara
&& rSel
.nStartPos
< rSel
.nEndPos
) )
60 { nPara
= rSel
.nStartPara
;
61 nPos
= rSel
.nStartPos
;
64 { nPara
= rSel
.nEndPara
;
69 bool SmEditWindow::IsInlineEditEnabled()
71 return SmViewShell::IsInlineEditEnabled();
75 SmEditWindow::SmEditWindow( SmCmdBoxWindow
&rMyCmdBoxWin
) :
76 Window (&rMyCmdBoxWin
, WB_BORDER
),
77 DropTargetHelper ( this ),
78 rCmdBox (rMyCmdBoxWin
),
79 aModifyIdle ("SmEditWindow ModifyIdle"),
80 aCursorMoveIdle ("SmEditWindow CursorMoveIdle")
83 SetHelpId(HID_SMA_COMMAND_WIN_EDIT
);
84 SetMapMode(MapMode(MapUnit::MapPixel
));
86 // Even RTL languages don't use RTL for math
89 // compare DataChanged
90 SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );
92 aModifyIdle
.SetInvokeHandler(LINK(this, SmEditWindow
, ModifyTimerHdl
));
93 aModifyIdle
.SetPriority(TaskPriority::LOWEST
);
95 if (!IsInlineEditEnabled())
97 aCursorMoveIdle
.SetInvokeHandler(LINK(this, SmEditWindow
, CursorMoveTimerHdl
));
98 aCursorMoveIdle
.SetPriority(TaskPriority::LOWEST
);
101 // if not called explicitly the this edit window within the
102 // command window will just show an empty gray panel.
107 SmEditWindow::~SmEditWindow()
112 void SmEditWindow::dispose()
118 // clean up of classes used for accessibility
119 // must be done before EditView (and thus EditEngine) is no longer
120 // available for those classes.
121 if (mxAccessible
.is())
123 mxAccessible
->ClearWin(); // make Accessible nonfunctional
124 mxAccessible
.clear();
129 EditEngine
*pEditEngine
= pEditView
->GetEditEngine();
132 pEditEngine
->SetStatusEventHdl( Link
<EditStatus
&,void>() );
133 pEditEngine
->RemoveView( pEditView
.get() );
138 pHScrollBar
.disposeAndClear();
139 pVScrollBar
.disposeAndClear();
140 pScrollBox
.disposeAndClear();
142 DropTargetHelper::dispose();
143 vcl::Window::dispose();
146 OUString
SmEditWindow::GetSurroundingText() const
149 return pEditView
->GetSurroundingText();
153 Selection
SmEditWindow::GetSurroundingTextSelection() const
156 return pEditView
->GetSurroundingTextSelection();
157 return Selection(0, 0);
160 bool SmEditWindow::DeleteSurroundingText(const Selection
& rSelection
)
163 return pEditView
->DeleteSurroundingText(rSelection
);
167 void SmEditWindow::StartCursorMove()
169 if (!IsInlineEditEnabled())
170 aCursorMoveIdle
.Stop();
173 void SmEditWindow::InvalidateSlots()
175 SfxBindings
& rBind
= GetView()->GetViewFrame()->GetBindings();
176 rBind
.Invalidate(SID_COPY
);
177 rBind
.Invalidate(SID_CUT
);
178 rBind
.Invalidate(SID_DELETE
);
181 SmViewShell
* SmEditWindow::GetView()
183 return rCmdBox
.GetView();
187 SmDocShell
* SmEditWindow::GetDoc()
189 SmViewShell
*pView
= rCmdBox
.GetView();
190 return pView
? pView
->GetDoc() : nullptr;
193 EditView
* SmEditWindow::GetEditView()
195 return pEditView
.get();
198 EditEngine
* SmEditWindow::GetEditEngine()
200 EditEngine
*pEditEng
= nullptr;
202 pEditEng
= pEditView
->GetEditEngine();
205 SmDocShell
*pDoc
= GetDoc();
207 pEditEng
= &pDoc
->GetEditEngine();
212 void SmEditWindow::ApplySettings(vcl::RenderContext
& rRenderContext
)
214 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
215 rRenderContext
.SetBackground(rStyleSettings
.GetWindowColor());
218 void SmEditWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
220 Window::DataChanged( rDCEvt
);
222 if (!((rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
223 (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
) ||
224 ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
225 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
))))
228 EditEngine
*pEditEngine
= GetEditEngine();
229 SmDocShell
*pDoc
= GetDoc();
231 if (pEditEngine
&& pDoc
)
234 //! see also SmDocShell::GetEditEngine() !
236 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
238 pDoc
->UpdateEditEngineDefaultFonts(rStyleSettings
.GetFieldTextColor());
239 pEditEngine
->SetBackgroundColor(rStyleSettings
.GetFieldColor());
240 pEditEngine
->SetDefTab(sal_uInt16(GetTextWidth("XXXX")));
242 // forces new settings to be used
243 // unfortunately this resets the whole edit engine
244 // thus we need to save at least the text
245 OUString
aTxt( pEditEngine
->GetText() );
246 pEditEngine
->Clear(); //incorrect font size
247 pEditEngine
->SetText( aTxt
);
256 IMPL_LINK_NOARG( SmEditWindow
, ModifyTimerHdl
, Timer
*, void )
262 IMPL_LINK_NOARG(SmEditWindow
, CursorMoveTimerHdl
, Timer
*, void)
263 // every once in a while check cursor position (selection) of edit
264 // window and if it has changed (try to) set the formula-cursor
265 // according to that.
267 if (IsInlineEditEnabled())
270 ESelection
aNewSelection(GetSelection());
272 if (aNewSelection
!= aOldSelection
)
274 SmViewShell
*pView
= rCmdBox
.GetView();
277 // get row and column to look for
280 SmGetLeftSelectionPart(aNewSelection
, nRow
, nCol
);
283 pView
->GetGraphicWindow().SetCursorPos(static_cast<sal_uInt16
>(nRow
), nCol
);
284 aOldSelection
= aNewSelection
;
287 aCursorMoveIdle
.Stop();
290 void SmEditWindow::Resize()
297 // Resizes the edit engine to adjust to the size of the output area
298 const Size
aSize( pEditView
->GetOutputArea().GetSize() );
299 pEditView
->GetEditEngine()->SetPaperSize(aSize
);
301 pEditView
->SetOutputArea(AdjustScrollBars());
302 pEditView
->ShowCursor();
304 OSL_ENSURE( pEditView
->GetEditEngine(), "EditEngine missing" );
305 const tools::Long nMaxVisAreaStart
= pEditView
->GetEditEngine()->GetTextHeight() -
306 pEditView
->GetOutputArea().GetHeight();
307 if (pEditView
->GetVisArea().Top() > nMaxVisAreaStart
)
309 tools::Rectangle
aVisArea(pEditView
->GetVisArea() );
310 aVisArea
.SetTop( std::max
<tools::Long
>(nMaxVisAreaStart
, 0) );
311 aVisArea
.SetSize(pEditView
->GetOutputArea().GetSize());
312 pEditView
->SetVisArea(aVisArea
);
313 pEditView
->ShowCursor();
320 void SmEditWindow::MouseButtonUp(const MouseEvent
&rEvt
)
323 pEditView
->MouseButtonUp(rEvt
);
325 Window::MouseButtonUp (rEvt
);
327 if (!IsInlineEditEnabled())
328 CursorMoveTimerHdl(&aCursorMoveIdle
);
332 void SmEditWindow::MouseButtonDown(const MouseEvent
&rEvt
)
335 pEditView
->MouseButtonDown(rEvt
);
337 Window::MouseButtonDown (rEvt
);
342 void SmEditWindow::Command(const CommandEvent
& rCEvt
)
344 //pass alt press/release to parent impl
345 if (rCEvt
.GetCommand() == CommandEventId::ModKeyChange
)
347 Window::Command(rCEvt
);
351 bool bForwardEvt
= true;
352 if (rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
354 GetParent()->ToTop();
356 Point aPoint
= rCEvt
.GetMousePosPixel();
357 SmViewShell
* pViewSh
= rCmdBox
.GetView();
359 pViewSh
->GetViewFrame()->GetDispatcher()->ExecutePopup("edit", this, &aPoint
);
362 else if (rCEvt
.GetCommand() == CommandEventId::Wheel
)
363 bForwardEvt
= !HandleWheelCommands( rCEvt
);
369 pEditView
->Command(rCEvt
);
370 UserPossiblyChangedText();
373 Window::Command (rCEvt
);
377 bool SmEditWindow::HandleWheelCommands( const CommandEvent
&rCEvt
)
379 bool bCommandHandled
= false; // true if the CommandEvent needs not
380 // to be passed on (because it has fully
381 // been taken care of).
383 const CommandWheelData
* pWData
= rCEvt
.GetWheelData();
386 if (CommandWheelMode::ZOOM
== pWData
->GetMode())
387 bCommandHandled
= true; // no zooming in Command window
389 bCommandHandled
= HandleScrollCommand( rCEvt
, pHScrollBar
.get(), pVScrollBar
.get());
392 return bCommandHandled
;
395 void SmEditWindow::KeyInput(const KeyEvent
& rKEvt
)
397 if (rKEvt
.GetKeyCode().GetCode() == KEY_ESCAPE
)
399 bool bCallBase
= true;
400 SfxViewShell
* pViewShell
= GetView();
401 if ( dynamic_cast<const SmViewShell
*>(pViewShell
) )
403 // Terminate possible InPlace mode
404 bCallBase
= !pViewShell
->Escape();
407 Window::KeyInput( rKEvt
);
413 bool autoClose
= false;
416 ESelection aSelection
= pEditView
->GetSelection();
417 // as we don't support RTL in Math, we need to swap values from selection when they were done
420 OUString selected
= pEditView
->GetEditEngine()->GetText(aSelection
);
422 // Check is auto close brackets/braces is disabled
423 SmModule
*pMod
= SM_MOD();
424 if (pMod
&& !pMod
->GetConfig()->IsAutoCloseBrackets())
426 else if (selected
.trim() == "<?>")
428 else if (selected
.isEmpty() && !aSelection
.HasRange())
430 selected
= pEditView
->GetEditEngine()->GetText(aSelection
.nEndPara
);
431 if (!selected
.isEmpty())
433 sal_Int32 index
= selected
.indexOf("\n", aSelection
.nEndPos
);
436 selected
= selected
.copy(index
, sal_Int32(aSelection
.nEndPos
-index
));
437 if (selected
.trim().isEmpty())
442 sal_Int32 length
= selected
.getLength();
443 if (aSelection
.nEndPos
== length
)
447 selected
= selected
.copy(aSelection
.nEndPos
);
448 if (selected
.trim().isEmpty())
457 if ( !pEditView
->PostKeyEvent(rKEvt
) )
459 SmViewShell
*pView
= GetView();
460 if ( pView
&& !pView
->KeyInput(rKEvt
) )
462 // F1 (help) leads to the destruction of this
464 if ( aModifyIdle
.IsActive() )
466 Window::KeyInput(rKEvt
);
470 // SFX has maybe called a slot of the view and thus (because of a hack in SFX)
471 // set the focus to the view
472 SfxViewShell
* pVShell
= GetView();
473 if ( dynamic_cast<const SmViewShell
*>(pVShell
) &&
474 static_cast<SmViewShell
*>(pVShell
)->GetGraphicWindow().HasFocus() )
482 UserPossiblyChangedText();
485 // get the current char of the key event
486 sal_Unicode cCharCode
= rKEvt
.GetCharCode();
489 if (cCharCode
== '{')
491 else if (cCharCode
== '[')
493 else if (cCharCode
== '(')
496 // auto close the current character only when needed
497 if (!sClose
.isEmpty() && autoClose
)
499 pEditView
->InsertText(sClose
);
500 // position it at center of brackets
501 aSelection
.nStartPos
+= 2;
502 aSelection
.nEndPos
= aSelection
.nStartPos
;
503 pEditView
->SetSelection(aSelection
);
510 void SmEditWindow::UserPossiblyChangedText()
512 // have doc-shell modified only for formula input/change and not
513 // cursor travelling and such things...
514 SmDocShell
*pDocShell
= GetDoc();
515 EditEngine
*pEditEngine
= GetEditEngine();
516 if (pDocShell
&& pEditEngine
&& pEditEngine
->IsModified())
517 pDocShell
->SetModified(true);
521 void SmEditWindow::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
525 pEditView
->Paint(rRect
, &rRenderContext
);
528 void SmEditWindow::CreateEditView()
530 EditEngine
*pEditEngine
= GetEditEngine();
532 //! pEditEngine and pEditView may be 0.
533 //! For example when the program is used by the document-converter
534 if (pEditView
|| !pEditEngine
)
537 pEditView
.reset(new EditView(pEditEngine
, this));
538 pEditEngine
->InsertView( pEditView
.get() );
541 pVScrollBar
= VclPtr
<ScrollBar
>::Create(this, WinBits(WB_VSCROLL
));
543 pHScrollBar
= VclPtr
<ScrollBar
>::Create(this, WinBits(WB_HSCROLL
));
545 pScrollBox
= VclPtr
<ScrollBarBox
>::Create(this);
546 pVScrollBar
->SetScrollHdl(LINK(this, SmEditWindow
, ScrollHdl
));
547 pHScrollBar
->SetScrollHdl(LINK(this, SmEditWindow
, ScrollHdl
));
548 pVScrollBar
->EnableDrag();
549 pHScrollBar
->EnableDrag();
551 pEditView
->SetOutputArea(AdjustScrollBars());
553 ESelection eSelection
;
555 pEditView
->SetSelection(eSelection
);
557 pEditView
->ShowCursor();
559 pEditEngine
->SetStatusEventHdl( LINK(this, SmEditWindow
, EditStatusHdl
) );
560 SetPointer(pEditView
->GetPointer());
562 SetScrollBarRanges();
566 IMPL_LINK_NOARG( SmEditWindow
, EditStatusHdl
, EditStatus
&, void )
572 IMPL_LINK( SmEditWindow
, ScrollHdl
, ScrollBar
*, /*pScrollBar*/, void )
574 OSL_ENSURE(pEditView
, "EditView missing");
577 pEditView
->SetVisArea(tools::Rectangle(Point(pHScrollBar
->GetThumbPos(),
578 pVScrollBar
->GetThumbPos()),
579 pEditView
->GetVisArea().GetSize()));
580 pEditView
->Invalidate();
584 tools::Rectangle
SmEditWindow::AdjustScrollBars()
586 const Size
aOut( GetOutputSizePixel() );
587 tools::Rectangle
aRect( Point(), aOut
);
589 if (pVScrollBar
&& pHScrollBar
&& pScrollBox
)
591 const tools::Long nTmp
= GetSettings().GetStyleSettings().GetScrollBarSize();
592 Point
aPt( aRect
.TopRight() ); aPt
.AdjustX( -(nTmp
-1) );
593 pVScrollBar
->SetPosSizePixel( aPt
, Size(nTmp
, aOut
.Height() - nTmp
));
595 aPt
= aRect
.BottomLeft(); aPt
.AdjustY( -(nTmp
- 1) );
596 pHScrollBar
->SetPosSizePixel( aPt
, Size(aOut
.Width() - nTmp
, nTmp
));
598 aPt
.setX( pHScrollBar
->GetSizePixel().Width() );
599 aPt
.setY( pVScrollBar
->GetSizePixel().Height() );
600 pScrollBox
->SetPosSizePixel(aPt
, Size(nTmp
, nTmp
));
602 aRect
.SetRight( aPt
.X() - 2 );
603 aRect
.SetBottom( aPt
.Y() - 2 );
608 void SmEditWindow::SetScrollBarRanges()
610 // Extra method, not InitScrollBars, since it's also being used for EditEngine events
611 EditEngine
*pEditEngine
= GetEditEngine();
612 if (pVScrollBar
&& pHScrollBar
&& pEditEngine
&& pEditView
)
614 tools::Long nTmp
= pEditEngine
->GetTextHeight();
615 pVScrollBar
->SetRange(Range(0, nTmp
));
616 pVScrollBar
->SetThumbPos(pEditView
->GetVisArea().Top());
618 nTmp
= pEditEngine
->GetPaperSize().Width();
619 pHScrollBar
->SetRange(Range(0,nTmp
));
620 pHScrollBar
->SetThumbPos(pEditView
->GetVisArea().Left());
624 void SmEditWindow::InitScrollBars()
626 if (!(pVScrollBar
&& pHScrollBar
&& pScrollBox
&& pEditView
))
629 const Size
aOut( pEditView
->GetOutputArea().GetSize() );
630 pVScrollBar
->SetVisibleSize(aOut
.Height());
631 pVScrollBar
->SetPageSize(aOut
.Height() * 8 / 10);
632 pVScrollBar
->SetLineSize(aOut
.Height() * 2 / 10);
634 pHScrollBar
->SetVisibleSize(aOut
.Width());
635 pHScrollBar
->SetPageSize(aOut
.Width() * 8 / 10);
636 pHScrollBar
->SetLineSize(SCROLL_LINE
);
638 SetScrollBarRanges();
646 OUString
SmEditWindow::GetText() const
649 EditEngine
*pEditEngine
= const_cast< SmEditWindow
* >(this)->GetEditEngine();
650 OSL_ENSURE( pEditEngine
, "EditEngine missing" );
652 aText
= pEditEngine
->GetText();
657 void SmEditWindow::SetText(const OUString
& rText
)
659 EditEngine
*pEditEngine
= GetEditEngine();
660 OSL_ENSURE( pEditEngine
, "EditEngine missing" );
661 if (!pEditEngine
|| pEditEngine
->IsModified())
667 ESelection eSelection
= pEditView
->GetSelection();
669 pEditEngine
->SetText(rText
);
670 pEditEngine
->ClearModifyFlag();
672 // Restarting the timer here, prevents calling the handlers for other (currently inactive)
676 pEditView
->SetSelection(eSelection
);
680 void SmEditWindow::GetFocus()
684 if (mxAccessible
.is())
686 // Note: will implicitly send the AccessibleStateType::FOCUSED event
687 ::accessibility::AccessibleTextHelper
*pHelper
= mxAccessible
->GetTextHelper();
694 EditEngine
*pEditEngine
= GetEditEngine();
696 pEditEngine
->SetStatusEventHdl( LINK(this, SmEditWindow
, EditStatusHdl
) );
698 //Let SmViewShell know we got focus
699 if(GetView() && IsInlineEditEnabled())
700 GetView()->SetInsertIntoEditWindow(true);
704 void SmEditWindow::LoseFocus()
706 EditEngine
*pEditEngine
= GetEditEngine();
708 pEditEngine
->SetStatusEventHdl( Link
<EditStatus
&,void>() );
712 if (mxAccessible
.is())
714 // Note: will implicitly send the AccessibleStateType::FOCUSED event
715 ::accessibility::AccessibleTextHelper
*pHelper
= mxAccessible
->GetTextHelper();
717 pHelper
->SetFocus(false);
722 bool SmEditWindow::IsAllSelected() const
725 EditEngine
*pEditEngine
= const_cast<SmEditWindow
*>(this)->GetEditEngine();
726 OSL_ENSURE( pEditView
, "NULL pointer" );
727 OSL_ENSURE( pEditEngine
, "NULL pointer" );
728 if (pEditEngine
&& pEditView
)
730 ESelection
eSelection( pEditView
->GetSelection() );
731 sal_Int32 nParaCnt
= pEditEngine
->GetParagraphCount();
734 sal_Int32 nTextLen
= pEditEngine
->GetText().getLength();
735 bRes
= !eSelection
.nStartPos
&& (eSelection
.nEndPos
== nTextLen
- 1);
739 bRes
= !eSelection
.nStartPara
&& (eSelection
.nEndPara
== nParaCnt
- 1);
745 void SmEditWindow::SelectAll()
747 OSL_ENSURE( pEditView
, "NULL pointer" );
750 // ALL as last two parameters refers to the end of the text
751 pEditView
->SetSelection( ESelection( 0, 0, EE_PARA_ALL
, EE_TEXTPOS_ALL
) );
755 void SmEditWindow::MarkError(const Point
&rPos
)
757 OSL_ENSURE( pEditView
, "EditView missing" );
760 const sal_uInt16 nCol
= sal::static_int_cast
< sal_uInt16
>(rPos
.X());
761 const sal_uInt16 nRow
= sal::static_int_cast
< sal_uInt16
>(rPos
.Y() - 1);
763 pEditView
->SetSelection(ESelection(nRow
, nCol
- 1, nRow
, nCol
));
768 // Makes selection to next <?> symbol
769 void SmEditWindow::SelNextMark()
771 EditEngine
*pEditEngine
= GetEditEngine();
772 OSL_ENSURE( pEditView
, "NULL pointer" );
773 OSL_ENSURE( pEditEngine
, "NULL pointer" );
774 if (!pEditEngine
|| !pEditView
)
777 ESelection eSelection
= pEditView
->GetSelection();
778 sal_Int32 nPos
= eSelection
.nEndPos
;
779 sal_Int32 nCounts
= pEditEngine
->GetParagraphCount();
781 while (eSelection
.nEndPara
< nCounts
)
783 OUString aText
= pEditEngine
->GetText(eSelection
.nEndPara
);
784 nPos
= aText
.indexOf("<?>", nPos
);
787 pEditView
->SetSelection(ESelection(
788 eSelection
.nEndPara
, nPos
, eSelection
.nEndPara
, nPos
+ 3));
793 eSelection
.nEndPara
++;
797 void SmEditWindow::SelPrevMark()
799 EditEngine
*pEditEngine
= GetEditEngine();
800 OSL_ENSURE( pEditEngine
, "NULL pointer" );
801 OSL_ENSURE( pEditView
, "NULL pointer" );
802 if (!(pEditEngine
&& pEditView
))
805 ESelection eSelection
= pEditView
->GetSelection();
806 sal_Int32 nPara
= eSelection
.nStartPara
;
807 sal_Int32 nMax
= eSelection
.nStartPos
;
808 OUString
aText(pEditEngine
->GetText(nPara
));
809 const OUString
aMark("<?>");
812 while ( (nPos
= aText
.lastIndexOf(aMark
, nMax
)) < 0 )
816 aText
= pEditEngine
->GetText(nPara
);
817 nMax
= aText
.getLength();
819 pEditView
->SetSelection(ESelection(nPara
, nPos
, nPara
, nPos
+ 3));
822 bool SmEditWindow::HasMark(const OUString
& rText
)
823 // returns true iff 'rText' contains a mark
825 return rText
.indexOf("<?>") != -1;
828 void SmEditWindow::MouseMove(const MouseEvent
&rEvt
)
831 pEditView
->MouseMove(rEvt
);
834 sal_Int8
SmEditWindow::AcceptDrop( const AcceptDropEvent
& /*rEvt*/ )
836 return DND_ACTION_NONE
;
839 sal_Int8
SmEditWindow::ExecuteDrop( const ExecuteDropEvent
& /*rEvt*/ )
841 return DND_ACTION_NONE
;
844 ESelection
SmEditWindow::GetSelection() const
846 // pointer may be 0 when reloading a document and the old view
847 // was already destroyed
848 //(OSL_ENSURE( pEditView, "NULL pointer" );
851 eSel
= pEditView
->GetSelection();
855 void SmEditWindow::SetSelection(const ESelection
&rSel
)
857 OSL_ENSURE( pEditView
, "NULL pointer" );
859 pEditView
->SetSelection(rSel
);
863 bool SmEditWindow::IsEmpty() const
865 EditEngine
*pEditEngine
= const_cast<SmEditWindow
*>(this)->GetEditEngine();
866 bool bEmpty
= ( pEditEngine
&& pEditEngine
->GetTextLen() == 0 );
870 bool SmEditWindow::IsSelected() const
872 return pEditView
&& pEditView
->HasSelection();
876 void SmEditWindow::UpdateStatus( bool bSetDocModified
)
878 SmModule
*pMod
= SM_MOD();
879 if (pMod
&& pMod
->GetConfig()->IsAutoRedraw())
881 if ( bSetDocModified
)
882 GetDoc()->SetModified();
885 void SmEditWindow::Cut()
887 OSL_ENSURE( pEditView
, "EditView missing" );
895 void SmEditWindow::Copy()
897 OSL_ENSURE( pEditView
, "EditView missing" );
902 void SmEditWindow::Paste()
904 OSL_ENSURE( pEditView
, "EditView missing" );
912 void SmEditWindow::Delete()
914 OSL_ENSURE( pEditView
, "EditView missing" );
917 pEditView
->DeleteSelected();
922 void SmEditWindow::InsertText(const OUString
& rText
)
924 OSL_ENSURE( pEditView
, "EditView missing" );
928 // Note: Insertion of a space in front of commands is done here and
929 // in SmEditWindow::InsertCommand.
930 ESelection aSelection
= pEditView
->GetSelection();
931 OUString aCurrentFormula
= pEditView
->GetEditEngine()->GetText();
932 sal_Int32 nStartIndex
= 0;
934 // get the start position (when we get a multi line formula)
935 for (sal_Int32 nParaPos
= 0; nParaPos
< aSelection
.nStartPara
; nParaPos
++)
936 nStartIndex
= aCurrentFormula
.indexOf("\n", nStartIndex
) + 1;
938 nStartIndex
+= aSelection
.nStartPos
;
940 // TODO: unify this function with the InsertCommand: The do the same thing for different
942 OUString
string(rText
);
944 OUString
selected(pEditView
->GetSelected());
945 // if we have text selected, use it in the first placeholder
946 if (!selected
.isEmpty())
947 string
= string
.replaceFirst("<?>", selected
);
949 // put a space before a new command if not in the beginning of a line
950 if (aSelection
.nStartPos
> 0 && aCurrentFormula
[nStartIndex
- 1] != ' ')
951 string
= " " + string
;
954 fdo#65588 - Elements Dock: Scrollbar moves into input window
955 This change "solves" the visual problem. But I don't think so
956 this is the best solution.
960 pEditView
->InsertText(string
);
965 // Remember start of the selection and move the cursor there afterwards.
966 aSelection
.nEndPara
= aSelection
.nStartPara
;
969 aSelection
.nEndPos
= aSelection
.nStartPos
;
970 pEditView
->SetSelection(aSelection
);
974 { // set selection after inserted text
975 aSelection
.nEndPos
= aSelection
.nStartPos
+ string
.getLength();
976 aSelection
.nStartPos
= aSelection
.nEndPos
;
977 pEditView
->SetSelection(aSelection
);
985 void SmEditWindow::Flush()
987 EditEngine
*pEditEngine
= GetEditEngine();
988 if (pEditEngine
&& pEditEngine
->IsModified())
990 pEditEngine
->ClearModifyFlag();
991 SmViewShell
*pViewSh
= rCmdBox
.GetView();
994 std::unique_ptr
<SfxStringItem
> pTextToFlush
= std::make_unique
<SfxStringItem
>(SID_TEXT
, GetText());
995 pViewSh
->GetViewFrame()->GetDispatcher()->ExecuteList(
996 SID_TEXT
, SfxCallMode::RECORD
,
997 { pTextToFlush
.get() });
1000 if (aCursorMoveIdle
.IsActive())
1002 aCursorMoveIdle
.Stop();
1003 CursorMoveTimerHdl(&aCursorMoveIdle
);
1007 void SmEditWindow::DeleteEditView()
1011 std::unique_ptr
<EditEngine
> xEditEngine(pEditView
->GetEditEngine());
1014 xEditEngine
->SetStatusEventHdl( Link
<EditStatus
&,void>() );
1015 xEditEngine
->RemoveView( pEditView
.get() );
1021 uno::Reference
< XAccessible
> SmEditWindow::CreateAccessible()
1023 if (!mxAccessible
.is())
1025 mxAccessible
.set(new SmEditAccessible( this ));
1026 mxAccessible
->Init();
1028 return uno::Reference
< XAccessible
>(mxAccessible
.get());
1031 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */