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>
21 #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
22 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
23 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
24 #include <toolkit/helper/vclunohelper.hxx>
27 #include "starmath.hrc"
29 #include <vcl/menu.hxx>
30 #include <vcl/settings.hxx>
32 #include <editeng/editview.hxx>
33 #include <editeng/editeng.hxx>
34 #include <editeng/editstat.hxx>
35 #include <editeng/eeitem.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <svl/intitem.hxx>
38 #include <svl/itempool.hxx>
39 #include <svl/stritem.hxx>
40 #include <editeng/fhgtitem.hxx>
41 #include <editeng/wghtitem.hxx>
42 #include <editeng/lrspitem.hxx>
43 #include <svl/itemset.hxx>
44 #include <editeng/fontitem.hxx>
45 #include <sfx2/viewfrm.hxx>
49 #include "document.hxx"
51 #include "accessibility.hxx"
54 #define SCROLL_LINE 24
57 using namespace com::sun::star::accessibility
;
58 using namespace com::sun::star
;
59 using namespace com::sun::star::uno
;
64 void SmGetLeftSelectionPart(const ESelection
&rSel
,
65 sal_Int32
&nPara
, sal_uInt16
&nPos
)
66 // returns paragraph number and position of the selections left part
68 // compare start and end of selection and use the one that comes first
69 if ( rSel
.nStartPara
< rSel
.nEndPara
70 || (rSel
.nStartPara
== rSel
.nEndPara
&& rSel
.nStartPos
< rSel
.nEndPos
) )
71 { nPara
= rSel
.nStartPara
;
72 nPos
= rSel
.nStartPos
;
75 { nPara
= rSel
.nEndPara
;
80 bool SmEditWindow::IsInlineEditEnabled()
82 SmViewShell
*pView
= GetView();
83 return pView
&& pView
->IsInlineEditEnabled();
88 SmEditWindow::SmEditWindow( SmCmdBoxWindow
&rMyCmdBoxWin
) :
89 Window (&rMyCmdBoxWin
),
90 DropTargetHelper ( this ),
92 rCmdBox (rMyCmdBoxWin
)
94 SetHelpId(HID_SMA_COMMAND_WIN_EDIT
);
95 SetMapMode(MAP_PIXEL
);
97 // Even RTL languages don't use RTL for math
100 ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
102 // compare DataChanged
103 SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );
105 aModifyIdle
.SetIdleHdl(LINK(this, SmEditWindow
, ModifyTimerHdl
));
106 aModifyIdle
.SetPriority(SchedulerPriority::LOWEST
);
108 if (!IsInlineEditEnabled())
110 aCursorMoveIdle
.SetIdleHdl(LINK(this, SmEditWindow
, CursorMoveTimerHdl
));
111 aCursorMoveIdle
.SetPriority(SchedulerPriority::LOWEST
);
114 // if not called explicitly the this edit window within the
115 // command window will just show an empty gray panel.
120 SmEditWindow::~SmEditWindow()
125 void SmEditWindow::dispose()
131 // clean up of classes used for accessibility
132 // must be done before EditView (and thus EditEngine) is no longer
133 // available for those classes.
136 pAccessible
->ClearWin(); // make Accessible defunctional
140 // Note: memory for pAccessible will be freed when the reference
141 // xAccessible is released. FIXME: horribly redundant lifecycle ! ...
145 EditEngine
*pEditEngine
= pEditView
->GetEditEngine();
148 pEditEngine
->SetStatusEventHdl( Link
<>() );
149 pEditEngine
->RemoveView( pEditView
.get() );
154 pHScrollBar
.disposeAndClear();
155 pVScrollBar
.disposeAndClear();
156 pScrollBox
.disposeAndClear();
158 vcl::Window::dispose();
161 void SmEditWindow::StartCursorMove()
163 if (!IsInlineEditEnabled())
164 aCursorMoveIdle
.Stop();
167 void SmEditWindow::InvalidateSlots()
169 SfxBindings
& rBind
= GetView()->GetViewFrame()->GetBindings();
170 rBind
.Invalidate(SID_COPY
);
171 rBind
.Invalidate(SID_CUT
);
172 rBind
.Invalidate(SID_DELETE
);
175 SmViewShell
* SmEditWindow::GetView()
177 return rCmdBox
.GetView();
181 SmDocShell
* SmEditWindow::GetDoc()
183 SmViewShell
*pView
= rCmdBox
.GetView();
184 return pView
? pView
->GetDoc() : 0;
187 EditView
* SmEditWindow::GetEditView()
189 return pEditView
.get();
192 EditEngine
* SmEditWindow::GetEditEngine()
194 EditEngine
*pEditEng
= 0;
196 pEditEng
= pEditView
->GetEditEngine();
199 SmDocShell
*pDoc
= GetDoc();
201 pEditEng
= &pDoc
->GetEditEngine();
207 SfxItemPool
* SmEditWindow::GetEditEngineItemPool()
209 SmDocShell
*pDoc
= GetDoc();
210 return pDoc
? &pDoc
->GetEditEngineItemPool() : 0;
213 void SmEditWindow::ApplyColorConfigValues( const svtools::ColorConfig
&rColorCfg
)
215 // Note: SetBackground still done in SmEditWindow::DataChanged
216 #if OSL_DEBUG_LEVEL > 1
217 // ColorData nVal = rColorCfg.GetColorValue(svtools::FONTCOLOR).nColor;
219 SetTextColor( rColorCfg
.GetColorValue(svtools::FONTCOLOR
).nColor
);
223 void SmEditWindow::DataChanged( const DataChangedEvent
& )
225 const StyleSettings
aSettings( GetSettings().GetStyleSettings() );
227 // FIXME RenderContext
229 ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
230 SetBackground( aSettings
.GetWindowColor() );
232 // edit fields in other Applications use this font instead of
233 // the application font thus we use this one too
234 SetPointFont(*this, aSettings
.GetFieldFont() /*aSettings.GetAppFont()*/);
236 EditEngine
*pEditEngine
= GetEditEngine();
237 SfxItemPool
*pEditEngineItemPool
= GetEditEngineItemPool();
239 if (pEditEngine
&& pEditEngineItemPool
)
242 //! see also SmDocShell::GetEditEngine() !
245 pEditEngine
->SetDefTab(sal_uInt16(GetTextWidth(OUString("XXXX"))));
247 SetEditEngineDefaultFonts(*pEditEngineItemPool
);
249 // forces new settings to be used
250 // unfortunately this resets the whole edit engine
251 // thus we need to save at least the text
252 OUString
aTxt( pEditEngine
->GetText( LINEEND_LF
) );
253 pEditEngine
->Clear(); //incorrect font size
254 pEditEngine
->SetText( aTxt
);
261 IMPL_LINK_NOARG_TYPED( SmEditWindow
, ModifyTimerHdl
, Idle
*, void )
267 IMPL_LINK_NOARG_TYPED(SmEditWindow
, CursorMoveTimerHdl
, Idle
*, void)
268 // every once in a while check cursor position (selection) of edit
269 // window and if it has changed (try to) set the formula-cursor
270 // according to that.
272 if (IsInlineEditEnabled())
275 ESelection
aNewSelection(GetSelection());
277 if (!aNewSelection
.IsEqual(aOldSelection
))
279 SmViewShell
*pView
= rCmdBox
.GetView();
282 // get row and column to look for
285 SmGetLeftSelectionPart(aNewSelection
, nRow
, nCol
);
288 pView
->GetGraphicWindow().SetCursorPos(static_cast<sal_uInt16
>(nRow
), nCol
);
289 aOldSelection
= aNewSelection
;
292 aCursorMoveIdle
.Stop();
295 void SmEditWindow::Resize()
302 pEditView
->SetOutputArea(AdjustScrollBars());
303 pEditView
->ShowCursor();
305 OSL_ENSURE( pEditView
->GetEditEngine(), "EditEngine missing" );
306 const long nMaxVisAreaStart
= pEditView
->GetEditEngine()->GetTextHeight() -
307 pEditView
->GetOutputArea().GetHeight();
308 if (pEditView
->GetVisArea().Top() > nMaxVisAreaStart
)
310 Rectangle
aVisArea(pEditView
->GetVisArea() );
311 aVisArea
.Top() = (nMaxVisAreaStart
> 0 ) ? nMaxVisAreaStart
: 0;
312 aVisArea
.SetSize(pEditView
->GetOutputArea().GetSize());
313 pEditView
->SetVisArea(aVisArea
);
314 pEditView
->ShowCursor();
321 void SmEditWindow::MouseButtonUp(const MouseEvent
&rEvt
)
324 pEditView
->MouseButtonUp(rEvt
);
326 Window::MouseButtonUp (rEvt
);
328 if (!IsInlineEditEnabled())
329 CursorMoveTimerHdl(&aCursorMoveIdle
);
333 void SmEditWindow::MouseButtonDown(const MouseEvent
&rEvt
)
336 pEditView
->MouseButtonDown(rEvt
);
338 Window::MouseButtonDown (rEvt
);
343 void SmEditWindow::Command(const CommandEvent
& rCEvt
)
345 bool bForwardEvt
= true;
346 if (rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
348 GetParent()->ToTop();
350 Point aPoint
= rCEvt
.GetMousePosPixel();
351 std::unique_ptr
<PopupMenu
> xPopupMenu(new PopupMenu(SmResId(RID_COMMANDMENU
)));
353 // added for replaceability of context menus
355 ::com::sun::star::ui::ContextMenuExecuteEvent aEvent
;
356 aEvent
.SourceWindow
= VCLUnoHelper::GetInterface( this );
357 aEvent
.ExecutePosition
.X
= aPoint
.X();
358 aEvent
.ExecutePosition
.Y
= aPoint
.Y();
360 if ( GetView()->TryContextMenuInterception( *xPopupMenu
, sDummy
, pMenu
, aEvent
) )
364 xPopupMenu
.reset(static_cast<PopupMenu
*>(pMenu
));
368 xPopupMenu
->SetSelectHdl(LINK(this, SmEditWindow
, MenuSelectHdl
));
370 xPopupMenu
->Execute( this, aPoint
);
373 else if (rCEvt
.GetCommand() == CommandEventId::Wheel
)
374 bForwardEvt
= !HandleWheelCommands( rCEvt
);
379 pEditView
->Command( rCEvt
);
381 Window::Command (rCEvt
);
386 bool SmEditWindow::HandleWheelCommands( const CommandEvent
&rCEvt
)
388 bool bCommandHandled
= false; // true if the CommandEvent needs not
389 // to be passed on (because it has fully
390 // been taken care of).
392 const CommandWheelData
* pWData
= rCEvt
.GetWheelData();
395 if (CommandWheelMode::ZOOM
== pWData
->GetMode())
396 bCommandHandled
= true; // no zooming in Command window
398 bCommandHandled
= HandleScrollCommand( rCEvt
, pHScrollBar
.get(), pVScrollBar
.get());
401 return bCommandHandled
;
405 IMPL_LINK( SmEditWindow
, MenuSelectHdl
, Menu
*, pMenu
)
407 SmViewShell
*pViewSh
= rCmdBox
.GetView();
409 pViewSh
->GetViewFrame()->GetDispatcher()->Execute(
410 SID_INSERTCOMMAND
, SfxCallMode::RECORD
,
411 new SfxInt16Item(SID_INSERTCOMMAND
, pMenu
->GetCurItemId()), 0L);
415 void SmEditWindow::KeyInput(const KeyEvent
& rKEvt
)
417 if (rKEvt
.GetKeyCode().GetCode() == KEY_ESCAPE
)
419 bool bCallBase
= true;
420 SfxViewShell
* pViewShell
= GetView();
421 if ( pViewShell
&& pViewShell
->ISA(SmViewShell
) )
423 // Terminate possible InPlace mode
424 bCallBase
= !pViewShell
->Escape();
427 Window::KeyInput( rKEvt
);
433 bool autoClose
= false;
436 ESelection aSelection
= pEditView
->GetSelection();
437 // as we don't support RTL in Math, we need to swap values from selection when they were done
440 OUString selected
= pEditView
->GetEditEngine()->GetText(aSelection
);
442 if (selected
.trim() == "<?>")
444 else if (selected
.isEmpty() && !aSelection
.HasRange())
446 selected
= pEditView
->GetEditEngine()->GetText(aSelection
.nEndPara
);
447 if (!selected
.isEmpty())
449 sal_Int32 index
= selected
.indexOf("\n", aSelection
.nEndPos
);
452 selected
= selected
.copy(index
, sal_Int32(aSelection
.nEndPos
-index
));
453 if (selected
.trim().isEmpty())
458 sal_Int32 length
= selected
.getLength();
459 if (aSelection
.nEndPos
== length
)
463 selected
= selected
.copy(aSelection
.nEndPos
);
464 if (selected
.trim().isEmpty())
473 if ( !pEditView
->PostKeyEvent(rKEvt
) )
475 SmViewShell
*pView
= GetView();
476 if ( pView
&& !pView
->KeyInput(rKEvt
) )
478 // F1 (help) leads to the destruction of this
480 if ( aModifyIdle
.IsActive() )
482 Window::KeyInput(rKEvt
);
486 // SFX has maybe called a slot of the view and thus (because of a hack in SFX)
487 // set the focus to the view
488 SfxViewShell
* pVShell
= GetView();
489 if ( pVShell
&& pVShell
->ISA(SmViewShell
) &&
490 static_cast<SmViewShell
*>(pVShell
)->GetGraphicWindow().HasFocus() )
498 // have doc-shell modified only for formula input/change and not
499 // cursor travelling and such things...
500 SmDocShell
*pDocShell
= GetDoc();
501 EditEngine
*pEditEngine
= GetEditEngine();
502 if (pDocShell
&& pEditEngine
)
503 pDocShell
->SetModified(pEditEngine
->IsModified());
507 // get the current char of the key event
508 sal_Unicode cCharCode
= rKEvt
.GetCharCode();
511 if (cCharCode
== '{')
513 else if (cCharCode
== '[')
515 else if (cCharCode
== '(')
518 // auto close the current character only when needed
519 if (!sClose
.isEmpty() && autoClose
)
521 pEditView
->InsertText(sClose
);
522 // position it at center of brackets
523 aSelection
.nStartPos
+= 2;
524 aSelection
.nEndPos
= aSelection
.nStartPos
;
525 pEditView
->SetSelection(aSelection
);
532 void SmEditWindow::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
)
536 pEditView
->Paint(rRect
, &rRenderContext
);
539 void SmEditWindow::CreateEditView()
541 EditEngine
*pEditEngine
= GetEditEngine();
543 //! pEditEngine and pEditView may be 0.
544 //! For example when the program is used by the document-converter
545 if (!pEditView
&& pEditEngine
)
547 pEditView
.reset(new EditView(pEditEngine
, this));
548 pEditEngine
->InsertView( pEditView
.get() );
551 pVScrollBar
= VclPtr
<ScrollBar
>::Create(this, WinBits(WB_VSCROLL
));
553 pHScrollBar
= VclPtr
<ScrollBar
>::Create(this, WinBits(WB_HSCROLL
));
555 pScrollBox
= VclPtr
<ScrollBarBox
>::Create(this);
556 pVScrollBar
->SetScrollHdl(LINK(this, SmEditWindow
, ScrollHdl
));
557 pHScrollBar
->SetScrollHdl(LINK(this, SmEditWindow
, ScrollHdl
));
558 pVScrollBar
->EnableDrag( true );
559 pHScrollBar
->EnableDrag( true );
561 pEditView
->SetOutputArea(AdjustScrollBars());
563 ESelection eSelection
;
565 pEditView
->SetSelection(eSelection
);
567 pEditView
->ShowCursor(true, true);
569 pEditEngine
->SetStatusEventHdl( LINK(this, SmEditWindow
, EditStatusHdl
) );
570 SetPointer(pEditView
->GetPointer());
572 SetScrollBarRanges();
577 IMPL_LINK( SmEditWindow
, EditStatusHdl
, EditStatus
*, /*pStat*/ )
588 IMPL_LINK( SmEditWindow
, ScrollHdl
, ScrollBar
*, /*pScrollBar*/ )
590 OSL_ENSURE(pEditView
, "EditView missing");
593 pEditView
->SetVisArea(Rectangle(Point(pHScrollBar
->GetThumbPos(),
594 pVScrollBar
->GetThumbPos()),
595 pEditView
->GetVisArea().GetSize()));
596 pEditView
->Invalidate();
601 Rectangle
SmEditWindow::AdjustScrollBars()
603 const Size
aOut( GetOutputSizePixel() );
605 Rectangle
aRect( aPoint
, aOut
);
607 if (pVScrollBar
&& pHScrollBar
&& pScrollBox
)
609 const long nTmp
= GetSettings().GetStyleSettings().GetScrollBarSize();
610 Point
aPt( aRect
.TopRight() ); aPt
.X() -= nTmp
-1L;
611 pVScrollBar
->SetPosSizePixel( aPt
, Size(nTmp
, aOut
.Height() - nTmp
));
613 aPt
= aRect
.BottomLeft(); aPt
.Y() -= nTmp
- 1L;
614 pHScrollBar
->SetPosSizePixel( aPt
, Size(aOut
.Width() - nTmp
, nTmp
));
616 aPt
.X() = pHScrollBar
->GetSizePixel().Width();
617 aPt
.Y() = pVScrollBar
->GetSizePixel().Height();
618 pScrollBox
->SetPosSizePixel(aPt
, Size(nTmp
, nTmp
));
620 aRect
.Right() = aPt
.X() - 2;
621 aRect
.Bottom() = aPt
.Y() - 2;
626 void SmEditWindow::SetScrollBarRanges()
628 // Extra method, not InitScrollBars, since it's also being used for EditEngine events
629 EditEngine
*pEditEngine
= GetEditEngine();
630 if (pVScrollBar
&& pHScrollBar
&& pEditEngine
&& pEditView
)
632 long nTmp
= pEditEngine
->GetTextHeight();
633 pVScrollBar
->SetRange(Range(0, nTmp
));
634 pVScrollBar
->SetThumbPos(pEditView
->GetVisArea().Top());
636 nTmp
= pEditEngine
->GetPaperSize().Width();
637 pHScrollBar
->SetRange(Range(0,nTmp
));
638 pHScrollBar
->SetThumbPos(pEditView
->GetVisArea().Left());
642 void SmEditWindow::InitScrollBars()
644 if (pVScrollBar
&& pHScrollBar
&& pScrollBox
&& pEditView
)
646 const Size
aOut( pEditView
->GetOutputArea().GetSize() );
647 pVScrollBar
->SetVisibleSize(aOut
.Height());
648 pVScrollBar
->SetPageSize(aOut
.Height() * 8 / 10);
649 pVScrollBar
->SetLineSize(aOut
.Height() * 2 / 10);
651 pHScrollBar
->SetVisibleSize(aOut
.Width());
652 pHScrollBar
->SetPageSize(aOut
.Width() * 8 / 10);
653 pHScrollBar
->SetLineSize(SCROLL_LINE
);
655 SetScrollBarRanges();
664 OUString
SmEditWindow::GetText() const
667 EditEngine
*pEditEngine
= const_cast< SmEditWindow
* >(this)->GetEditEngine();
668 OSL_ENSURE( pEditEngine
, "EditEngine missing" );
670 aText
= pEditEngine
->GetText( LINEEND_LF
);
675 void SmEditWindow::SetText(const OUString
& rText
)
677 EditEngine
*pEditEngine
= GetEditEngine();
678 OSL_ENSURE( pEditEngine
, "EditEngine missing" );
679 if (pEditEngine
&& !pEditEngine
->IsModified())
684 ESelection eSelection
= pEditView
->GetSelection();
686 pEditEngine
->SetText(rText
);
687 pEditEngine
->ClearModifyFlag();
689 // Restarting the timer here, prevents calling the handlers for other (currently inactive)
693 pEditView
->SetSelection(eSelection
);
698 void SmEditWindow::GetFocus()
702 if (xAccessible
.is())
704 // Note: will implicitly send the AccessibleStateType::FOCUSED event
705 ::accessibility::AccessibleTextHelper
*pHelper
= pAccessible
->GetTextHelper();
707 pHelper
->SetFocus(true);
712 EditEngine
*pEditEngine
= GetEditEngine();
714 pEditEngine
->SetStatusEventHdl( LINK(this, SmEditWindow
, EditStatusHdl
) );
716 //Let SmViewShell know we got focus
717 if(GetView() && IsInlineEditEnabled())
718 GetView()->SetInsertIntoEditWindow(true);
722 void SmEditWindow::LoseFocus()
724 EditEngine
*pEditEngine
= GetEditEngine();
726 pEditEngine
->SetStatusEventHdl( Link
<>() );
730 if (xAccessible
.is())
732 // Note: will implicitly send the AccessibleStateType::FOCUSED event
733 ::accessibility::AccessibleTextHelper
*pHelper
= pAccessible
->GetTextHelper();
735 pHelper
->SetFocus(false);
740 bool SmEditWindow::IsAllSelected() const
743 EditEngine
*pEditEngine
= (const_cast<SmEditWindow
*>(this))->GetEditEngine();
744 OSL_ENSURE( pEditView
, "NULL pointer" );
745 OSL_ENSURE( pEditEngine
, "NULL pointer" );
746 if (pEditEngine
&& pEditView
)
748 ESelection
eSelection( pEditView
->GetSelection() );
749 sal_Int32 nParaCnt
= pEditEngine
->GetParagraphCount();
752 sal_Int32 nTextLen
= pEditEngine
->GetText( LINEEND_LF
).getLength();
753 bRes
= !eSelection
.nStartPos
&& (eSelection
.nEndPos
== nTextLen
- 1);
757 bRes
= !eSelection
.nStartPara
&& (eSelection
.nEndPara
== nParaCnt
- 1);
763 void SmEditWindow::SelectAll()
765 OSL_ENSURE( pEditView
, "NULL pointer" );
768 // ALL as last two parameters refers to the end of the text
769 pEditView
->SetSelection( ESelection( 0, 0, EE_PARA_ALL
, EE_TEXTPOS_ALL
) );
773 void SmEditWindow::InsertCommand(sal_uInt16 nCommand
)
775 OSL_ENSURE( pEditView
, "EditView missing" );
778 ESelection aSelection
= pEditView
->GetSelection();
780 OSL_ENSURE( pEditView
, "NULL pointer" );
781 OUString aText
= SM_RESSTR(nCommand
);
783 OUString aCurrentFormula
= pEditView
->GetEditEngine()->GetText();
784 sal_Int32 nStartIndex
= 0;
785 sal_Int32 nEndIndex
= 0;
787 // get the start position (when we get a multi line formula)
788 for (sal_Int32 nParaPos
= 0; nParaPos
< aSelection
.nStartPara
; nParaPos
++)
789 nStartIndex
= aCurrentFormula
.indexOf("\n", nStartIndex
) + 1;
791 nStartIndex
+= aSelection
.nStartPos
;
793 // get the end position (when we get a multi line formula)
794 for (sal_Int32 nParaPos
= 0; nParaPos
< aSelection
.nEndPara
; nParaPos
++)
795 nEndIndex
= aCurrentFormula
.indexOf("\n", nEndIndex
) + 1;
797 nEndIndex
+= aSelection
.nEndPos
;
799 // remove right space of current symbol if there already is one
800 if (nEndIndex
< aCurrentFormula
.getLength() &&
801 aCurrentFormula
[nEndIndex
] == ' ')
802 aText
= aText
.trim();
804 // put a space before a new command if not in the beginning of a line
805 if (aSelection
.nStartPos
> 0 && aCurrentFormula
[nStartIndex
- 1] != ' ')
808 pEditView
->InsertText(aText
);
810 // Remember start of the selection and move the cursor there afterwards.
811 aSelection
.nEndPara
= aSelection
.nStartPara
;
814 aSelection
.nEndPos
= aSelection
.nStartPos
;
815 pEditView
->SetSelection(aSelection
);
819 { // set selection after inserted text
820 aSelection
.nEndPos
= aSelection
.nStartPos
+ aText
.getLength();
821 aSelection
.nStartPos
= aSelection
.nEndPos
;
822 pEditView
->SetSelection(aSelection
);
831 void SmEditWindow::MarkError(const Point
&rPos
)
833 OSL_ENSURE( pEditView
, "EditView missing" );
836 const sal_uInt16 nCol
= sal::static_int_cast
< sal_uInt16
>(rPos
.X());
837 const sal_uInt16 nRow
= sal::static_int_cast
< sal_uInt16
>(rPos
.Y() - 1);
839 pEditView
->SetSelection(ESelection(nRow
, nCol
- 1, nRow
, nCol
));
844 // Makes selection to next <?> symbol
845 void SmEditWindow::SelNextMark()
847 EditEngine
*pEditEngine
= GetEditEngine();
848 OSL_ENSURE( pEditView
, "NULL pointer" );
849 OSL_ENSURE( pEditEngine
, "NULL pointer" );
850 if (pEditEngine
&& pEditView
)
852 ESelection eSelection
= pEditView
->GetSelection();
853 sal_Int32 nPos
= eSelection
.nEndPos
;
854 sal_Int32 nCounts
= pEditEngine
->GetParagraphCount();
856 while (eSelection
.nEndPara
< nCounts
)
858 OUString aText
= pEditEngine
->GetText(eSelection
.nEndPara
);
859 nPos
= aText
.indexOf("<?>", nPos
);
862 pEditView
->SetSelection(ESelection(
863 eSelection
.nEndPara
, nPos
, eSelection
.nEndPara
, nPos
+ 3));
868 eSelection
.nEndPara
++;
873 void SmEditWindow::SelPrevMark()
875 EditEngine
*pEditEngine
= GetEditEngine();
876 OSL_ENSURE( pEditEngine
, "NULL pointer" );
877 OSL_ENSURE( pEditView
, "NULL pointer" );
878 if (pEditEngine
&& pEditView
)
880 ESelection eSelection
= pEditView
->GetSelection();
882 sal_Int32 nMax
= eSelection
.nStartPos
;
883 OUString
aText(pEditEngine
->GetText(eSelection
.nStartPara
));
884 OUString
aMark("<?>");
885 sal_Int32 nCounts
= pEditEngine
->GetParagraphCount();
889 sal_Int32 nMarkIndex
= aText
.indexOf(aMark
);
890 while ((nMarkIndex
< nMax
) && (nMarkIndex
!= -1))
893 nMarkIndex
= aText
.indexOf(aMark
, nMarkIndex
+ 1);
898 eSelection
.nStartPara
--;
899 aText
= pEditEngine
->GetText(eSelection
.nStartPara
);
900 nMax
= aText
.getLength();
903 while ((eSelection
.nStartPara
< nCounts
) &&
908 pEditView
->SetSelection(ESelection(
909 eSelection
.nStartPara
, nPos
, eSelection
.nStartPara
, nPos
+ 3));
914 bool SmEditWindow::HasMark(const OUString
& rText
)
915 // returns true iff 'rText' contains a mark
917 return rText
.indexOf("<?>") != -1;
920 void SmEditWindow::MouseMove(const MouseEvent
&rEvt
)
923 pEditView
->MouseMove(rEvt
);
926 sal_Int8
SmEditWindow::AcceptDrop( const AcceptDropEvent
& /*rEvt*/ )
928 return DND_ACTION_NONE
;
931 sal_Int8
SmEditWindow::ExecuteDrop( const ExecuteDropEvent
& /*rEvt*/ )
933 return DND_ACTION_NONE
;
936 ESelection
SmEditWindow::GetSelection() const
938 // pointer may be 0 when reloading a document and the old view
939 // was already destroyed
940 //(OSL_ENSURE( pEditView, "NULL pointer" );
943 eSel
= pEditView
->GetSelection();
947 void SmEditWindow::SetSelection(const ESelection
&rSel
)
949 OSL_ENSURE( pEditView
, "NULL pointer" );
951 pEditView
->SetSelection(rSel
);
955 bool SmEditWindow::IsEmpty() const
957 EditEngine
*pEditEngine
= (const_cast<SmEditWindow
*>(this))->GetEditEngine();
958 bool bEmpty
= ( pEditEngine
&& pEditEngine
->GetTextLen() == 0 );
962 bool SmEditWindow::IsSelected() const
964 return pEditView
&& pEditView
->HasSelection();
968 void SmEditWindow::UpdateStatus( bool bSetDocModified
)
970 SmModule
*pMod
= SM_MOD();
971 if (pMod
&& pMod
->GetConfig()->IsAutoRedraw())
973 if ( bSetDocModified
)
974 GetDoc()->SetModified(true);
977 void SmEditWindow::Cut()
979 OSL_ENSURE( pEditView
, "EditView missing" );
987 void SmEditWindow::Copy()
989 OSL_ENSURE( pEditView
, "EditView missing" );
994 void SmEditWindow::Paste()
996 OSL_ENSURE( pEditView
, "EditView missing" );
1004 void SmEditWindow::Delete()
1006 OSL_ENSURE( pEditView
, "EditView missing" );
1009 pEditView
->DeleteSelected();
1014 void SmEditWindow::InsertText(const OUString
& rText
)
1016 OSL_ENSURE( pEditView
, "EditView missing" );
1019 // Note: Insertion of a space in front of commands is done here and
1020 // in SmEditWindow::InsertCommand.
1021 ESelection aSelection
= pEditView
->GetSelection();
1022 OUString aCurrentFormula
= pEditView
->GetEditEngine()->GetText();
1023 sal_Int32 nStartIndex
= 0;
1024 sal_Int32 nEndIndex
= 0;
1026 // get the start position (when we get a multi line formula)
1027 for (sal_Int32 nParaPos
= 0; nParaPos
< aSelection
.nStartPara
; nParaPos
++)
1028 nStartIndex
= aCurrentFormula
.indexOf("\n", nStartIndex
) + 1;
1030 nStartIndex
+= aSelection
.nStartPos
;
1032 // get the end position (when we get a multi line formula)
1033 for (sal_Int32 nParaPos
= 0; nParaPos
< aSelection
.nEndPara
; nParaPos
++)
1034 nEndIndex
= aCurrentFormula
.indexOf("\n", nEndIndex
) + 1;
1036 nEndIndex
+= aSelection
.nEndPos
;
1038 // TODO: unify this function with the InsertCommand: The do the same thing for different
1040 OUString
string(rText
);
1042 // put a space before a new command if not in the beginning of a line
1043 if (aSelection
.nStartPos
> 0 && aCurrentFormula
[nStartIndex
- 1] != ' ')
1044 string
= " " + string
;
1047 fdo#65588 - Elements Dock: Scrollbar moves into input window
1048 This change "solves" the visual problem. But I don't think so
1049 this is the best solution.
1051 pVScrollBar
->Hide();
1052 pHScrollBar
->Hide();
1053 pEditView
->InsertText(string
);
1055 pVScrollBar
->Show();
1056 pHScrollBar
->Show();
1058 // Remember start of the selection and move the cursor there afterwards.
1059 aSelection
.nEndPara
= aSelection
.nStartPara
;
1060 if (HasMark(string
))
1062 aSelection
.nEndPos
= aSelection
.nStartPos
;
1063 pEditView
->SetSelection(aSelection
);
1067 { // set selection after inserted text
1068 aSelection
.nEndPos
= aSelection
.nStartPos
+ string
.getLength();
1069 aSelection
.nStartPos
= aSelection
.nEndPos
;
1070 pEditView
->SetSelection(aSelection
);
1073 aModifyIdle
.Start();
1079 void SmEditWindow::Flush()
1081 EditEngine
*pEditEngine
= GetEditEngine();
1082 if (pEditEngine
&& pEditEngine
->IsModified())
1084 pEditEngine
->ClearModifyFlag();
1085 SmViewShell
*pViewSh
= rCmdBox
.GetView();
1088 pViewSh
->GetViewFrame()->GetDispatcher()->Execute(
1089 SID_TEXT
, SfxCallMode::RECORD
,
1090 new SfxStringItem(SID_TEXT
, GetText()), 0L);
1093 if (aCursorMoveIdle
.IsActive())
1095 aCursorMoveIdle
.Stop();
1096 CursorMoveTimerHdl(&aCursorMoveIdle
);
1100 void SmEditWindow::DeleteEditView( SmViewShell
& /*rView*/ )
1104 std::unique_ptr
<EditEngine
> xEditEngine(pEditView
->GetEditEngine());
1107 xEditEngine
->SetStatusEventHdl( Link
<>() );
1108 xEditEngine
->RemoveView( pEditView
.get() );
1114 uno::Reference
< XAccessible
> SmEditWindow::CreateAccessible()
1118 pAccessible
= new SmEditAccessible( this );
1119 xAccessible
= pAccessible
;
1120 pAccessible
->Init();
1125 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */