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 <com/sun/star/accessibility/XAccessible.hpp>
22 #include <starmath.hrc>
25 #include <vcl/menu.hxx>
26 #include <vcl/settings.hxx>
28 #include <editeng/editview.hxx>
29 #include <editeng/editeng.hxx>
30 #include <editeng/editstat.hxx>
31 #include <o3tl/make_unique.hxx>
32 #include <sfx2/dispatch.hxx>
33 #include <svl/stritem.hxx>
34 #include <sfx2/viewfrm.hxx>
35 #include <svx/AccessibleTextHelper.hxx>
39 #include <document.hxx>
40 #include "cfgitem.hxx"
41 #include "accessibility.hxx"
44 #define SCROLL_LINE 24
47 using namespace com::sun::star::accessibility
;
48 using namespace com::sun::star
;
51 void SmGetLeftSelectionPart(const ESelection
&rSel
,
52 sal_Int32
&nPara
, sal_uInt16
&nPos
)
53 // returns paragraph number and position of the selections left part
55 // compare start and end of selection and use the one that comes first
56 if ( rSel
.nStartPara
< rSel
.nEndPara
57 || (rSel
.nStartPara
== rSel
.nEndPara
&& rSel
.nStartPos
< rSel
.nEndPos
) )
58 { nPara
= rSel
.nStartPara
;
59 nPos
= rSel
.nStartPos
;
62 { nPara
= rSel
.nEndPara
;
67 bool SmEditWindow::IsInlineEditEnabled()
69 SmViewShell
*pView
= GetView();
70 return pView
&& pView
->IsInlineEditEnabled();
74 SmEditWindow::SmEditWindow( SmCmdBoxWindow
&rMyCmdBoxWin
) :
75 Window (&rMyCmdBoxWin
),
76 DropTargetHelper ( this ),
77 rCmdBox (rMyCmdBoxWin
),
78 aModifyIdle ("SmEditWindow ModifyIdle"),
79 aCursorMoveIdle ("SmEditWindow CursorMoveIdle")
82 SetHelpId(HID_SMA_COMMAND_WIN_EDIT
);
83 SetMapMode(MapMode(MapUnit::MapPixel
));
85 // Even RTL languages don't use RTL for math
88 ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
90 // compare DataChanged
91 SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );
93 aModifyIdle
.SetInvokeHandler(LINK(this, SmEditWindow
, ModifyTimerHdl
));
94 aModifyIdle
.SetPriority(TaskPriority::LOWEST
);
96 if (!IsInlineEditEnabled())
98 aCursorMoveIdle
.SetInvokeHandler(LINK(this, SmEditWindow
, CursorMoveTimerHdl
));
99 aCursorMoveIdle
.SetPriority(TaskPriority::LOWEST
);
102 // if not called explicitly the this edit window within the
103 // command window will just show an empty gray panel.
108 SmEditWindow::~SmEditWindow()
113 void SmEditWindow::dispose()
119 // clean up of classes used for accessibility
120 // must be done before EditView (and thus EditEngine) is no longer
121 // available for those classes.
122 if (mxAccessible
.is())
124 mxAccessible
->ClearWin(); // make Accessible nonfunctional
125 mxAccessible
.clear();
130 EditEngine
*pEditEngine
= pEditView
->GetEditEngine();
133 pEditEngine
->SetStatusEventHdl( Link
<EditStatus
&,void>() );
134 pEditEngine
->RemoveView( pEditView
.get() );
139 pHScrollBar
.disposeAndClear();
140 pVScrollBar
.disposeAndClear();
141 pScrollBox
.disposeAndClear();
143 DropTargetHelper::dispose();
144 vcl::Window::dispose();
147 void SmEditWindow::StartCursorMove()
149 if (!IsInlineEditEnabled())
150 aCursorMoveIdle
.Stop();
153 void SmEditWindow::InvalidateSlots()
155 SfxBindings
& rBind
= GetView()->GetViewFrame()->GetBindings();
156 rBind
.Invalidate(SID_COPY
);
157 rBind
.Invalidate(SID_CUT
);
158 rBind
.Invalidate(SID_DELETE
);
161 SmViewShell
* SmEditWindow::GetView()
163 return rCmdBox
.GetView();
167 SmDocShell
* SmEditWindow::GetDoc()
169 SmViewShell
*pView
= rCmdBox
.GetView();
170 return pView
? pView
->GetDoc() : nullptr;
173 EditView
* SmEditWindow::GetEditView()
175 return pEditView
.get();
178 EditEngine
* SmEditWindow::GetEditEngine()
180 EditEngine
*pEditEng
= nullptr;
182 pEditEng
= pEditView
->GetEditEngine();
185 SmDocShell
*pDoc
= GetDoc();
187 pEditEng
= &pDoc
->GetEditEngine();
192 void SmEditWindow::ApplyColorConfigValues( const svtools::ColorConfig
&rColorCfg
)
194 // Note: SetBackground still done in SmEditWindow::DataChanged
195 SetTextColor( rColorCfg
.GetColorValue(svtools::FONTCOLOR
).nColor
);
199 void SmEditWindow::DataChanged( const DataChangedEvent
& )
201 const StyleSettings
aSettings( GetSettings().GetStyleSettings() );
203 // FIXME RenderContext
205 ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
206 SetBackground( aSettings
.GetWindowColor() );
208 // edit fields in other Applications use this font instead of
209 // the application font thus we use this one too
210 SetPointFont(*this, aSettings
.GetFieldFont() /*aSettings.GetAppFont()*/);
212 EditEngine
*pEditEngine
= GetEditEngine();
213 SmDocShell
*pDoc
= GetDoc();
215 if (pEditEngine
&& pDoc
)
218 //! see also SmDocShell::GetEditEngine() !
221 pEditEngine
->SetDefTab(sal_uInt16(GetTextWidth("XXXX")));
223 SetEditEngineDefaultFonts(pDoc
->GetEditEngineItemPool(), pDoc
->GetLinguOptions());
225 // forces new settings to be used
226 // unfortunately this resets the whole edit engine
227 // thus we need to save at least the text
228 OUString
aTxt( pEditEngine
->GetText() );
229 pEditEngine
->Clear(); //incorrect font size
230 pEditEngine
->SetText( aTxt
);
237 IMPL_LINK_NOARG( SmEditWindow
, ModifyTimerHdl
, Timer
*, void )
243 IMPL_LINK_NOARG(SmEditWindow
, CursorMoveTimerHdl
, Timer
*, void)
244 // every once in a while check cursor position (selection) of edit
245 // window and if it has changed (try to) set the formula-cursor
246 // according to that.
248 if (IsInlineEditEnabled())
251 ESelection
aNewSelection(GetSelection());
253 if (aNewSelection
!= aOldSelection
)
255 SmViewShell
*pView
= rCmdBox
.GetView();
258 // get row and column to look for
261 SmGetLeftSelectionPart(aNewSelection
, nRow
, nCol
);
264 pView
->GetGraphicWindow().SetCursorPos(static_cast<sal_uInt16
>(nRow
), nCol
);
265 aOldSelection
= aNewSelection
;
268 aCursorMoveIdle
.Stop();
271 void SmEditWindow::Resize()
278 pEditView
->SetOutputArea(AdjustScrollBars());
279 pEditView
->ShowCursor();
281 OSL_ENSURE( pEditView
->GetEditEngine(), "EditEngine missing" );
282 const long nMaxVisAreaStart
= pEditView
->GetEditEngine()->GetTextHeight() -
283 pEditView
->GetOutputArea().GetHeight();
284 if (pEditView
->GetVisArea().Top() > nMaxVisAreaStart
)
286 tools::Rectangle
aVisArea(pEditView
->GetVisArea() );
287 aVisArea
.SetTop( std::max
<long>(nMaxVisAreaStart
, 0) );
288 aVisArea
.SetSize(pEditView
->GetOutputArea().GetSize());
289 pEditView
->SetVisArea(aVisArea
);
290 pEditView
->ShowCursor();
297 void SmEditWindow::MouseButtonUp(const MouseEvent
&rEvt
)
300 pEditView
->MouseButtonUp(rEvt
);
302 Window::MouseButtonUp (rEvt
);
304 if (!IsInlineEditEnabled())
305 CursorMoveTimerHdl(&aCursorMoveIdle
);
309 void SmEditWindow::MouseButtonDown(const MouseEvent
&rEvt
)
312 pEditView
->MouseButtonDown(rEvt
);
314 Window::MouseButtonDown (rEvt
);
319 void SmEditWindow::Command(const CommandEvent
& rCEvt
)
321 //pass alt press/release to parent impl
322 if (rCEvt
.GetCommand() == CommandEventId::ModKeyChange
)
324 Window::Command(rCEvt
);
328 bool bForwardEvt
= true;
329 if (rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
331 GetParent()->ToTop();
333 Point aPoint
= rCEvt
.GetMousePosPixel();
334 SmViewShell
* pViewSh
= rCmdBox
.GetView();
336 pViewSh
->GetViewFrame()->GetDispatcher()->ExecutePopup("edit", this, &aPoint
);
339 else if (rCEvt
.GetCommand() == CommandEventId::Wheel
)
340 bForwardEvt
= !HandleWheelCommands( rCEvt
);
345 pEditView
->Command( rCEvt
);
347 Window::Command (rCEvt
);
352 bool SmEditWindow::HandleWheelCommands( const CommandEvent
&rCEvt
)
354 bool bCommandHandled
= false; // true if the CommandEvent needs not
355 // to be passed on (because it has fully
356 // been taken care of).
358 const CommandWheelData
* pWData
= rCEvt
.GetWheelData();
361 if (CommandWheelMode::ZOOM
== pWData
->GetMode())
362 bCommandHandled
= true; // no zooming in Command window
364 bCommandHandled
= HandleScrollCommand( rCEvt
, pHScrollBar
.get(), pVScrollBar
.get());
367 return bCommandHandled
;
370 void SmEditWindow::KeyInput(const KeyEvent
& rKEvt
)
372 if (rKEvt
.GetKeyCode().GetCode() == KEY_ESCAPE
)
374 bool bCallBase
= true;
375 SfxViewShell
* pViewShell
= GetView();
376 if ( pViewShell
&& dynamic_cast<const SmViewShell
*>(pViewShell
) != nullptr )
378 // Terminate possible InPlace mode
379 bCallBase
= !pViewShell
->Escape();
382 Window::KeyInput( rKEvt
);
388 bool autoClose
= false;
391 ESelection aSelection
= pEditView
->GetSelection();
392 // as we don't support RTL in Math, we need to swap values from selection when they were done
395 OUString selected
= pEditView
->GetEditEngine()->GetText(aSelection
);
397 // Check is auto close brackets/braces is disabled
398 SmModule
*pMod
= SM_MOD();
399 if (pMod
&& !pMod
->GetConfig()->IsAutoCloseBrackets())
401 else if (selected
.trim() == "<?>")
403 else if (selected
.isEmpty() && !aSelection
.HasRange())
405 selected
= pEditView
->GetEditEngine()->GetText(aSelection
.nEndPara
);
406 if (!selected
.isEmpty())
408 sal_Int32 index
= selected
.indexOf("\n", aSelection
.nEndPos
);
411 selected
= selected
.copy(index
, sal_Int32(aSelection
.nEndPos
-index
));
412 if (selected
.trim().isEmpty())
417 sal_Int32 length
= selected
.getLength();
418 if (aSelection
.nEndPos
== length
)
422 selected
= selected
.copy(aSelection
.nEndPos
);
423 if (selected
.trim().isEmpty())
432 if ( !pEditView
->PostKeyEvent(rKEvt
) )
434 SmViewShell
*pView
= GetView();
435 if ( pView
&& !pView
->KeyInput(rKEvt
) )
437 // F1 (help) leads to the destruction of this
439 if ( aModifyIdle
.IsActive() )
441 Window::KeyInput(rKEvt
);
445 // SFX has maybe called a slot of the view and thus (because of a hack in SFX)
446 // set the focus to the view
447 SfxViewShell
* pVShell
= GetView();
448 if ( pVShell
&& dynamic_cast<const SmViewShell
*>(pVShell
) != nullptr &&
449 static_cast<SmViewShell
*>(pVShell
)->GetGraphicWindow().HasFocus() )
457 // have doc-shell modified only for formula input/change and not
458 // cursor travelling and such things...
459 SmDocShell
*pDocShell
= GetDoc();
460 EditEngine
*pEditEngine
= GetEditEngine();
461 if (pDocShell
&& pEditEngine
)
462 pDocShell
->SetModified(pEditEngine
->IsModified());
466 // get the current char of the key event
467 sal_Unicode cCharCode
= rKEvt
.GetCharCode();
470 if (cCharCode
== '{')
472 else if (cCharCode
== '[')
474 else if (cCharCode
== '(')
477 // auto close the current character only when needed
478 if (!sClose
.isEmpty() && autoClose
)
480 pEditView
->InsertText(sClose
);
481 // position it at center of brackets
482 aSelection
.nStartPos
+= 2;
483 aSelection
.nEndPos
= aSelection
.nStartPos
;
484 pEditView
->SetSelection(aSelection
);
491 void SmEditWindow::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
495 pEditView
->Paint(rRect
, &rRenderContext
);
498 void SmEditWindow::CreateEditView()
500 EditEngine
*pEditEngine
= GetEditEngine();
502 //! pEditEngine and pEditView may be 0.
503 //! For example when the program is used by the document-converter
504 if (!pEditView
&& pEditEngine
)
506 pEditView
.reset(new EditView(pEditEngine
, this));
507 pEditEngine
->InsertView( pEditView
.get() );
510 pVScrollBar
= VclPtr
<ScrollBar
>::Create(this, WinBits(WB_VSCROLL
));
512 pHScrollBar
= VclPtr
<ScrollBar
>::Create(this, WinBits(WB_HSCROLL
));
514 pScrollBox
= VclPtr
<ScrollBarBox
>::Create(this);
515 pVScrollBar
->SetScrollHdl(LINK(this, SmEditWindow
, ScrollHdl
));
516 pHScrollBar
->SetScrollHdl(LINK(this, SmEditWindow
, ScrollHdl
));
517 pVScrollBar
->EnableDrag();
518 pHScrollBar
->EnableDrag();
520 pEditView
->SetOutputArea(AdjustScrollBars());
522 ESelection eSelection
;
524 pEditView
->SetSelection(eSelection
);
526 pEditView
->ShowCursor();
528 pEditEngine
->SetStatusEventHdl( LINK(this, SmEditWindow
, EditStatusHdl
) );
529 SetPointer(pEditView
->GetPointer());
531 SetScrollBarRanges();
536 IMPL_LINK_NOARG( SmEditWindow
, EditStatusHdl
, EditStatus
&, void )
542 IMPL_LINK( SmEditWindow
, ScrollHdl
, ScrollBar
*, /*pScrollBar*/, void )
544 OSL_ENSURE(pEditView
, "EditView missing");
547 pEditView
->SetVisArea(tools::Rectangle(Point(pHScrollBar
->GetThumbPos(),
548 pVScrollBar
->GetThumbPos()),
549 pEditView
->GetVisArea().GetSize()));
550 pEditView
->Invalidate();
554 tools::Rectangle
SmEditWindow::AdjustScrollBars()
556 const Size
aOut( GetOutputSizePixel() );
557 tools::Rectangle
aRect( Point(), aOut
);
559 if (pVScrollBar
&& pHScrollBar
&& pScrollBox
)
561 const long nTmp
= GetSettings().GetStyleSettings().GetScrollBarSize();
562 Point
aPt( aRect
.TopRight() ); aPt
.AdjustX( -(nTmp
-1) );
563 pVScrollBar
->SetPosSizePixel( aPt
, Size(nTmp
, aOut
.Height() - nTmp
));
565 aPt
= aRect
.BottomLeft(); aPt
.AdjustY( -(nTmp
- 1) );
566 pHScrollBar
->SetPosSizePixel( aPt
, Size(aOut
.Width() - nTmp
, nTmp
));
568 aPt
.setX( pHScrollBar
->GetSizePixel().Width() );
569 aPt
.setY( pVScrollBar
->GetSizePixel().Height() );
570 pScrollBox
->SetPosSizePixel(aPt
, Size(nTmp
, nTmp
));
572 aRect
.SetRight( aPt
.X() - 2 );
573 aRect
.SetBottom( aPt
.Y() - 2 );
578 void SmEditWindow::SetScrollBarRanges()
580 // Extra method, not InitScrollBars, since it's also being used for EditEngine events
581 EditEngine
*pEditEngine
= GetEditEngine();
582 if (pVScrollBar
&& pHScrollBar
&& pEditEngine
&& pEditView
)
584 long nTmp
= pEditEngine
->GetTextHeight();
585 pVScrollBar
->SetRange(Range(0, nTmp
));
586 pVScrollBar
->SetThumbPos(pEditView
->GetVisArea().Top());
588 nTmp
= pEditEngine
->GetPaperSize().Width();
589 pHScrollBar
->SetRange(Range(0,nTmp
));
590 pHScrollBar
->SetThumbPos(pEditView
->GetVisArea().Left());
594 void SmEditWindow::InitScrollBars()
596 if (pVScrollBar
&& pHScrollBar
&& pScrollBox
&& pEditView
)
598 const Size
aOut( pEditView
->GetOutputArea().GetSize() );
599 pVScrollBar
->SetVisibleSize(aOut
.Height());
600 pVScrollBar
->SetPageSize(aOut
.Height() * 8 / 10);
601 pVScrollBar
->SetLineSize(aOut
.Height() * 2 / 10);
603 pHScrollBar
->SetVisibleSize(aOut
.Width());
604 pHScrollBar
->SetPageSize(aOut
.Width() * 8 / 10);
605 pHScrollBar
->SetLineSize(SCROLL_LINE
);
607 SetScrollBarRanges();
616 OUString
SmEditWindow::GetText() const
619 EditEngine
*pEditEngine
= const_cast< SmEditWindow
* >(this)->GetEditEngine();
620 OSL_ENSURE( pEditEngine
, "EditEngine missing" );
622 aText
= pEditEngine
->GetText();
627 void SmEditWindow::SetText(const OUString
& rText
)
629 EditEngine
*pEditEngine
= GetEditEngine();
630 OSL_ENSURE( pEditEngine
, "EditEngine missing" );
631 if (pEditEngine
&& !pEditEngine
->IsModified())
636 ESelection eSelection
= pEditView
->GetSelection();
638 pEditEngine
->SetText(rText
);
639 pEditEngine
->ClearModifyFlag();
641 // Restarting the timer here, prevents calling the handlers for other (currently inactive)
645 pEditView
->SetSelection(eSelection
);
650 void SmEditWindow::GetFocus()
654 if (mxAccessible
.is())
656 // Note: will implicitly send the AccessibleStateType::FOCUSED event
657 ::accessibility::AccessibleTextHelper
*pHelper
= mxAccessible
->GetTextHelper();
664 EditEngine
*pEditEngine
= GetEditEngine();
666 pEditEngine
->SetStatusEventHdl( LINK(this, SmEditWindow
, EditStatusHdl
) );
668 //Let SmViewShell know we got focus
669 if(GetView() && IsInlineEditEnabled())
670 GetView()->SetInsertIntoEditWindow(true);
674 void SmEditWindow::LoseFocus()
676 EditEngine
*pEditEngine
= GetEditEngine();
678 pEditEngine
->SetStatusEventHdl( Link
<EditStatus
&,void>() );
682 if (mxAccessible
.is())
684 // Note: will implicitly send the AccessibleStateType::FOCUSED event
685 ::accessibility::AccessibleTextHelper
*pHelper
= mxAccessible
->GetTextHelper();
687 pHelper
->SetFocus(false);
692 bool SmEditWindow::IsAllSelected() const
695 EditEngine
*pEditEngine
= const_cast<SmEditWindow
*>(this)->GetEditEngine();
696 OSL_ENSURE( pEditView
, "NULL pointer" );
697 OSL_ENSURE( pEditEngine
, "NULL pointer" );
698 if (pEditEngine
&& pEditView
)
700 ESelection
eSelection( pEditView
->GetSelection() );
701 sal_Int32 nParaCnt
= pEditEngine
->GetParagraphCount();
704 sal_Int32 nTextLen
= pEditEngine
->GetText().getLength();
705 bRes
= !eSelection
.nStartPos
&& (eSelection
.nEndPos
== nTextLen
- 1);
709 bRes
= !eSelection
.nStartPara
&& (eSelection
.nEndPara
== nParaCnt
- 1);
715 void SmEditWindow::SelectAll()
717 OSL_ENSURE( pEditView
, "NULL pointer" );
720 // ALL as last two parameters refers to the end of the text
721 pEditView
->SetSelection( ESelection( 0, 0, EE_PARA_ALL
, EE_TEXTPOS_ALL
) );
725 void SmEditWindow::MarkError(const Point
&rPos
)
727 OSL_ENSURE( pEditView
, "EditView missing" );
730 const sal_uInt16 nCol
= sal::static_int_cast
< sal_uInt16
>(rPos
.X());
731 const sal_uInt16 nRow
= sal::static_int_cast
< sal_uInt16
>(rPos
.Y() - 1);
733 pEditView
->SetSelection(ESelection(nRow
, nCol
- 1, nRow
, nCol
));
738 // Makes selection to next <?> symbol
739 void SmEditWindow::SelNextMark()
741 EditEngine
*pEditEngine
= GetEditEngine();
742 OSL_ENSURE( pEditView
, "NULL pointer" );
743 OSL_ENSURE( pEditEngine
, "NULL pointer" );
744 if (pEditEngine
&& pEditView
)
746 ESelection eSelection
= pEditView
->GetSelection();
747 sal_Int32 nPos
= eSelection
.nEndPos
;
748 sal_Int32 nCounts
= pEditEngine
->GetParagraphCount();
750 while (eSelection
.nEndPara
< nCounts
)
752 OUString aText
= pEditEngine
->GetText(eSelection
.nEndPara
);
753 nPos
= aText
.indexOf("<?>", nPos
);
756 pEditView
->SetSelection(ESelection(
757 eSelection
.nEndPara
, nPos
, eSelection
.nEndPara
, nPos
+ 3));
762 eSelection
.nEndPara
++;
767 void SmEditWindow::SelPrevMark()
769 EditEngine
*pEditEngine
= GetEditEngine();
770 OSL_ENSURE( pEditEngine
, "NULL pointer" );
771 OSL_ENSURE( pEditView
, "NULL pointer" );
772 if (pEditEngine
&& pEditView
)
774 ESelection eSelection
= pEditView
->GetSelection();
775 sal_Int32 nPara
= eSelection
.nStartPara
;
776 sal_Int32 nMax
= eSelection
.nStartPos
;
777 OUString
aText(pEditEngine
->GetText(nPara
));
778 const OUString
aMark("<?>");
781 while ( (nPos
= aText
.lastIndexOf(aMark
, nMax
)) < 0 )
785 aText
= pEditEngine
->GetText(nPara
);
786 nMax
= aText
.getLength();
788 pEditView
->SetSelection(ESelection(nPara
, nPos
, nPara
, nPos
+ 3));
792 bool SmEditWindow::HasMark(const OUString
& rText
)
793 // returns true iff 'rText' contains a mark
795 return rText
.indexOf("<?>") != -1;
798 void SmEditWindow::MouseMove(const MouseEvent
&rEvt
)
801 pEditView
->MouseMove(rEvt
);
804 sal_Int8
SmEditWindow::AcceptDrop( const AcceptDropEvent
& /*rEvt*/ )
806 return DND_ACTION_NONE
;
809 sal_Int8
SmEditWindow::ExecuteDrop( const ExecuteDropEvent
& /*rEvt*/ )
811 return DND_ACTION_NONE
;
814 ESelection
SmEditWindow::GetSelection() const
816 // pointer may be 0 when reloading a document and the old view
817 // was already destroyed
818 //(OSL_ENSURE( pEditView, "NULL pointer" );
821 eSel
= pEditView
->GetSelection();
825 void SmEditWindow::SetSelection(const ESelection
&rSel
)
827 OSL_ENSURE( pEditView
, "NULL pointer" );
829 pEditView
->SetSelection(rSel
);
833 bool SmEditWindow::IsEmpty() const
835 EditEngine
*pEditEngine
= const_cast<SmEditWindow
*>(this)->GetEditEngine();
836 bool bEmpty
= ( pEditEngine
&& pEditEngine
->GetTextLen() == 0 );
840 bool SmEditWindow::IsSelected() const
842 return pEditView
&& pEditView
->HasSelection();
846 void SmEditWindow::UpdateStatus( bool bSetDocModified
)
848 SmModule
*pMod
= SM_MOD();
849 if (pMod
&& pMod
->GetConfig()->IsAutoRedraw())
851 if ( bSetDocModified
)
852 GetDoc()->SetModified();
855 void SmEditWindow::Cut()
857 OSL_ENSURE( pEditView
, "EditView missing" );
865 void SmEditWindow::Copy()
867 OSL_ENSURE( pEditView
, "EditView missing" );
872 void SmEditWindow::Paste()
874 OSL_ENSURE( pEditView
, "EditView missing" );
882 void SmEditWindow::Delete()
884 OSL_ENSURE( pEditView
, "EditView missing" );
887 pEditView
->DeleteSelected();
892 void SmEditWindow::InsertText(const OUString
& rText
)
894 OSL_ENSURE( pEditView
, "EditView missing" );
897 // Note: Insertion of a space in front of commands is done here and
898 // in SmEditWindow::InsertCommand.
899 ESelection aSelection
= pEditView
->GetSelection();
900 OUString aCurrentFormula
= pEditView
->GetEditEngine()->GetText();
901 sal_Int32 nStartIndex
= 0;
903 // get the start position (when we get a multi line formula)
904 for (sal_Int32 nParaPos
= 0; nParaPos
< aSelection
.nStartPara
; nParaPos
++)
905 nStartIndex
= aCurrentFormula
.indexOf("\n", nStartIndex
) + 1;
907 nStartIndex
+= aSelection
.nStartPos
;
909 // TODO: unify this function with the InsertCommand: The do the same thing for different
911 OUString
string(rText
);
913 OUString
selected(pEditView
->GetSelected());
914 // if we have text selected, use it in the first placeholder
915 if (!selected
.isEmpty())
916 string
= string
.replaceFirst("<?>", selected
);
918 // put a space before a new command if not in the beginning of a line
919 if (aSelection
.nStartPos
> 0 && aCurrentFormula
[nStartIndex
- 1] != ' ')
920 string
= " " + string
;
923 fdo#65588 - Elements Dock: Scrollbar moves into input window
924 This change "solves" the visual problem. But I don't think so
925 this is the best solution.
929 pEditView
->InsertText(string
);
934 // Remember start of the selection and move the cursor there afterwards.
935 aSelection
.nEndPara
= aSelection
.nStartPara
;
938 aSelection
.nEndPos
= aSelection
.nStartPos
;
939 pEditView
->SetSelection(aSelection
);
943 { // set selection after inserted text
944 aSelection
.nEndPos
= aSelection
.nStartPos
+ string
.getLength();
945 aSelection
.nStartPos
= aSelection
.nEndPos
;
946 pEditView
->SetSelection(aSelection
);
955 void SmEditWindow::Flush()
957 EditEngine
*pEditEngine
= GetEditEngine();
958 if (pEditEngine
&& pEditEngine
->IsModified())
960 pEditEngine
->ClearModifyFlag();
961 SmViewShell
*pViewSh
= rCmdBox
.GetView();
964 std::unique_ptr
<SfxStringItem
> pTextToFlush
= o3tl::make_unique
<SfxStringItem
>(SID_TEXT
, GetText());
965 pViewSh
->GetViewFrame()->GetDispatcher()->ExecuteList(
966 SID_TEXT
, SfxCallMode::RECORD
,
967 { pTextToFlush
.get() });
970 if (aCursorMoveIdle
.IsActive())
972 aCursorMoveIdle
.Stop();
973 CursorMoveTimerHdl(&aCursorMoveIdle
);
977 void SmEditWindow::DeleteEditView()
981 std::unique_ptr
<EditEngine
> xEditEngine(pEditView
->GetEditEngine());
984 xEditEngine
->SetStatusEventHdl( Link
<EditStatus
&,void>() );
985 xEditEngine
->RemoveView( pEditView
.get() );
991 uno::Reference
< XAccessible
> SmEditWindow::CreateAccessible()
993 if (!mxAccessible
.is())
995 mxAccessible
.set(new SmEditAccessible( this ));
996 mxAccessible
->Init();
998 return uno::Reference
< XAccessible
>(mxAccessible
.get());
1001 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */