| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_starmath.hxx" |
| |
| |
| #include <com/sun/star/accessibility/XAccessible.hpp> |
| #include <com/sun/star/accessibility/AccessibleEventObject.hpp> |
| #include <com/sun/star/accessibility/AccessibleEventId.hpp> |
| #include <com/sun/star/accessibility/AccessibleStateType.hpp> |
| #include <toolkit/helper/vclunohelper.hxx> |
| |
| |
| #include "starmath.hrc" |
| #define ITEMID_FONT 1 |
| #define ITEMID_FONTHEIGHT 2 |
| #define ITEMID_LRSPACE 3 |
| #define ITEMID_WEIGHT 4 |
| |
| |
| #include <vcl/menu.hxx> |
| #include <editeng/editview.hxx> |
| #include <editeng/editeng.hxx> |
| #include <editeng/editstat.hxx> |
| #include <editeng/eeitem.hxx> |
| #include <sfx2/dispatch.hxx> |
| #include <svl/intitem.hxx> |
| #include <svl/itempool.hxx> |
| #include <svl/stritem.hxx> |
| #include <editeng/fhgtitem.hxx> |
| #include <editeng/wghtitem.hxx> |
| #include <editeng/lrspitem.hxx> |
| #include <svl/itemset.hxx> |
| #include <editeng/fontitem.hxx> |
| #include <sfx2/viewfrm.hxx> |
| |
| #include "edit.hxx" |
| #include "view.hxx" |
| #include "document.hxx" |
| #include "config.hxx" |
| |
| #define SCROLL_LINE 24 |
| |
| #define MINWIDTH 200 |
| #define MINHEIGHT 200 |
| #define MINSPLIT 40 |
| #define SPLITTERWIDTH 2 |
| |
| |
| using namespace com::sun::star::accessibility; |
| using namespace com::sun::star; |
| using namespace com::sun::star::uno; |
| |
| //////////////////////////////////////// |
| |
| |
| void SmGetLeftSelectionPart(const ESelection aSel, |
| sal_uInt16 &nPara, sal_uInt16 &nPos) |
| // returns paragraph number and position of the selections left part |
| { |
| // compare start and end of selection and use the one that comes first |
| if ( aSel.nStartPara < aSel.nEndPara |
| || (aSel.nStartPara == aSel.nEndPara && aSel.nStartPos < aSel.nEndPos) ) |
| { nPara = aSel.nStartPara; |
| nPos = aSel.nStartPos; |
| } |
| else |
| { nPara = aSel.nEndPara; |
| nPos = aSel.nEndPos; |
| } |
| } |
| |
| //////////////////////////////////////// |
| |
| SmEditWindow::SmEditWindow( SmCmdBoxWindow &rMyCmdBoxWin ) : |
| Window (&rMyCmdBoxWin), |
| DropTargetHelper ( this ), |
| pAccessible (0), |
| rCmdBox (rMyCmdBoxWin), |
| pEditView (0), |
| pHScrollBar (0), |
| pVScrollBar (0), |
| pScrollBox (0) |
| { |
| SetHelpId(HID_SMA_COMMAND_WIN_EDIT); |
| SetMapMode(MAP_PIXEL); |
| |
| // Even RTL languages don't use RTL for math |
| rCmdBox.GetEditWindow()->EnableRTL( sal_False ); |
| |
| ApplyColorConfigValues( SM_MOD()->GetColorConfig() ); |
| |
| // compare DataChanged |
| SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); |
| |
| aModifyTimer.SetTimeoutHdl(LINK(this, SmEditWindow, ModifyTimerHdl)); |
| aModifyTimer.SetTimeout(500); |
| |
| aCursorMoveTimer.SetTimeoutHdl(LINK(this, SmEditWindow, CursorMoveTimerHdl)); |
| aCursorMoveTimer.SetTimeout(500); |
| |
| // if not called explicitly the this edit window within the |
| // command window will just show an empty gray panel. |
| Show(); |
| } |
| |
| |
| SmEditWindow::~SmEditWindow() |
| { |
| aCursorMoveTimer.Stop(); |
| aModifyTimer.Stop(); |
| |
| |
| // #112565# clean up of classes used for accessibility |
| // must be done before EditView (and thus EditEngine) is no longer |
| // available for those classes. |
| if (pAccessible) |
| pAccessible->ClearWin(); // make Accessible defunctional |
| // Note: memory for pAccessible will be freed when the reference |
| // xAccessible is released. |
| |
| if (pEditView) |
| { |
| EditEngine *pEditEngine = pEditView->GetEditEngine(); |
| if (pEditEngine) |
| { |
| pEditEngine->SetStatusEventHdl( Link() ); |
| pEditEngine->RemoveView( pEditView ); |
| } |
| } |
| delete pEditView; |
| delete pHScrollBar; |
| delete pVScrollBar; |
| delete pScrollBox; |
| } |
| |
| void SmEditWindow::InvalidateSlots() |
| { |
| SfxBindings& rBind = GetView()->GetViewFrame()->GetBindings(); |
| rBind.Invalidate(SID_COPY); |
| rBind.Invalidate(SID_CUT); |
| rBind.Invalidate(SID_DELETE); |
| } |
| |
| SmViewShell * SmEditWindow::GetView() |
| { |
| return rCmdBox.GetView(); |
| } |
| |
| |
| SmDocShell * SmEditWindow::GetDoc() |
| { |
| SmViewShell *pView = rCmdBox.GetView(); |
| return pView ? pView->GetDoc() : 0; |
| } |
| |
| |
| EditEngine * SmEditWindow::GetEditEngine() |
| { |
| EditEngine *pEditEng = 0; |
| if (pEditView) |
| pEditEng = pEditView->GetEditEngine(); |
| else |
| { |
| SmDocShell *pDoc = GetDoc(); |
| if (pDoc) |
| pEditEng = &pDoc->GetEditEngine(); |
| } |
| return pEditEng; |
| } |
| |
| |
| SfxItemPool * SmEditWindow::GetEditEngineItemPool() |
| { |
| SmDocShell *pDoc = GetDoc(); |
| return pDoc ? &pDoc->GetEditEngineItemPool() : 0; |
| } |
| |
| void SmEditWindow::ApplyColorConfigValues( const svtools::ColorConfig &rColorCfg ) |
| { |
| // Note: SetBackground still done in SmEditWindow::DataChanged |
| #if OSL_DEBUG_LEVEL > 1 |
| // ColorData nVal = rColorCfg.GetColorValue(svtools::FONTCOLOR).nColor; |
| #endif |
| SetTextColor( rColorCfg.GetColorValue(svtools::FONTCOLOR).nColor ); |
| Invalidate(); |
| } |
| |
| void SmEditWindow::DataChanged( const DataChangedEvent& ) |
| { |
| const StyleSettings aSettings( GetSettings().GetStyleSettings() ); |
| |
| ApplyColorConfigValues( SM_MOD()->GetColorConfig() ); |
| SetBackground( aSettings.GetWindowColor() ); |
| |
| // edit fields in other Applications use this font instead of |
| // the application font thus we use this one too |
| SetPointFont( aSettings.GetFieldFont() /*aSettings.GetAppFont()*/ ); |
| |
| EditEngine *pEditEngine = GetEditEngine(); |
| SfxItemPool *pEditEngineItemPool = GetEditEngineItemPool(); |
| |
| if (pEditEngine && pEditEngineItemPool) |
| { |
| //! |
| //! see also SmDocShell::GetEditEngine() ! |
| //! |
| |
| pEditEngine->SetDefTab( sal_uInt16( GetTextWidth( C2S("XXXX") ) ) ); |
| |
| SetEditEngineDefaultFonts( *pEditEngine, *pEditEngineItemPool ); |
| |
| // forces new settings to be used |
| // unfortunately this resets the whole edit engine |
| // thus we need to save at least the text |
| String aTxt( pEditEngine->GetText( LINEEND_LF ) ); |
| pEditEngine->Clear(); //#77957 incorrect font size |
| pEditEngine->SetText( aTxt ); |
| } |
| |
| AdjustScrollBars(); |
| Resize(); |
| } |
| |
| IMPL_LINK( SmEditWindow, ModifyTimerHdl, Timer *, EMPTYARG /*pTimer*/ ) |
| { |
| UpdateStatus(); |
| aModifyTimer.Stop(); |
| return 0; |
| } |
| |
| |
| IMPL_LINK(SmEditWindow, CursorMoveTimerHdl, Timer *, EMPTYARG /*pTimer*/) |
| // every once in a while check cursor position (selection) of edit |
| // window and if it has changed (try to) set the formula-cursor |
| // according to that. |
| { |
| ESelection aNewSelection (GetSelection()); |
| |
| if (!aNewSelection.IsEqual(aOldSelection)) |
| { SmViewShell *pView = rCmdBox.GetView(); |
| |
| if (pView) |
| { |
| // get row and column to look for |
| sal_uInt16 nRow, nCol; |
| SmGetLeftSelectionPart(aNewSelection, nRow, nCol); |
| nRow++; |
| nCol++; |
| |
| pView->GetGraphicWindow().SetCursorPos(nRow, nCol); |
| |
| aOldSelection = aNewSelection; |
| } |
| } |
| aCursorMoveTimer.Stop(); |
| |
| return 0; |
| } |
| |
| |
| void SmEditWindow::Resize() |
| { |
| if (!pEditView) |
| CreateEditView(); |
| |
| if (pEditView) |
| { |
| pEditView->SetOutputArea(AdjustScrollBars()); |
| pEditView->ShowCursor(); |
| |
| DBG_ASSERT( pEditView->GetEditEngine(), "EditEngine missing" ); |
| const long nMaxVisAreaStart = pEditView->GetEditEngine()->GetTextHeight() - |
| pEditView->GetOutputArea().GetHeight(); |
| if (pEditView->GetVisArea().Top() > nMaxVisAreaStart) |
| { |
| Rectangle aVisArea(pEditView->GetVisArea() ); |
| aVisArea.Top() = (nMaxVisAreaStart > 0 ) ? nMaxVisAreaStart : 0; |
| aVisArea.SetSize(pEditView->GetOutputArea().GetSize()); |
| pEditView->SetVisArea(aVisArea); |
| pEditView->ShowCursor(); |
| } |
| InitScrollBars(); |
| } |
| Invalidate(); |
| } |
| |
| void SmEditWindow::MouseButtonUp(const MouseEvent &rEvt) |
| { |
| if (pEditView) |
| pEditView->MouseButtonUp(rEvt); |
| else |
| Window::MouseButtonUp (rEvt); |
| |
| // ggf FormulaCursor neu positionieren |
| CursorMoveTimerHdl(&aCursorMoveTimer); |
| InvalidateSlots(); |
| } |
| |
| void SmEditWindow::MouseButtonDown(const MouseEvent &rEvt) |
| { |
| if (pEditView) |
| pEditView->MouseButtonDown(rEvt); |
| else |
| Window::MouseButtonDown (rEvt); |
| |
| GrabFocus(); |
| } |
| |
| void SmEditWindow::Command(const CommandEvent& rCEvt) |
| { |
| sal_Bool bForwardEvt = sal_True; |
| if (rCEvt.GetCommand() == COMMAND_CONTEXTMENU) |
| { |
| GetParent()->ToTop(); |
| |
| Point aPoint = rCEvt.GetMousePosPixel(); |
| PopupMenu* pPopupMenu = new PopupMenu(SmResId(RID_COMMANDMENU)); |
| |
| // added for replaceability of context menus #96085, #93782 |
| Menu* pMenu = NULL; |
| ::com::sun::star::ui::ContextMenuExecuteEvent aEvent; |
| aEvent.SourceWindow = VCLUnoHelper::GetInterface( this ); |
| aEvent.ExecutePosition.X = aPoint.X(); |
| aEvent.ExecutePosition.Y = aPoint.Y(); |
| ::rtl::OUString sDummy; |
| if ( GetView()->TryContextMenuInterception( *pPopupMenu, sDummy, pMenu, aEvent ) ) |
| { |
| if ( pMenu ) |
| { |
| delete pPopupMenu; |
| pPopupMenu = (PopupMenu*) pMenu; |
| } |
| } |
| |
| pPopupMenu->SetSelectHdl(LINK(this, SmEditWindow, MenuSelectHdl)); |
| |
| pPopupMenu->Execute( this, aPoint ); |
| delete pPopupMenu; |
| bForwardEvt = sal_False; |
| } |
| else if (rCEvt.GetCommand() == COMMAND_WHEEL) |
| bForwardEvt = !HandleWheelCommands( rCEvt ); |
| |
| if (bForwardEvt) |
| { |
| if (pEditView) |
| pEditView->Command( rCEvt ); |
| else |
| Window::Command (rCEvt); |
| } |
| } |
| |
| |
| sal_Bool SmEditWindow::HandleWheelCommands( const CommandEvent &rCEvt ) |
| { |
| sal_Bool bCommandHandled = sal_False; // true if the CommandEvent needs not |
| // to be passed on (because it has fully |
| // been taken care of). |
| |
| const CommandWheelData* pWData = rCEvt.GetWheelData(); |
| if (pWData) |
| { |
| if (COMMAND_WHEEL_ZOOM == pWData->GetMode()) |
| bCommandHandled = sal_True; // no zooming in Command window |
| else |
| bCommandHandled = HandleScrollCommand( rCEvt, pHScrollBar, pVScrollBar); |
| } |
| |
| return bCommandHandled; |
| } |
| |
| |
| IMPL_LINK_INLINE_START( SmEditWindow, MenuSelectHdl, Menu *, pMenu ) |
| { |
| SmViewShell *pViewSh = rCmdBox.GetView(); |
| if (pViewSh) |
| pViewSh->GetViewFrame()->GetDispatcher()->Execute( |
| SID_INSERTCOMMAND, SFX_CALLMODE_STANDARD, |
| new SfxInt16Item(SID_INSERTCOMMAND, pMenu->GetCurItemId()), 0L); |
| return 0; |
| } |
| IMPL_LINK_INLINE_END( SmEditWindow, MenuSelectHdl, Menu *, pMenu ) |
| |
| void SmEditWindow::KeyInput(const KeyEvent& rKEvt) |
| { |
| if (rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE) |
| { |
| sal_Bool bCallBase = sal_True; |
| SfxViewShell* pViewShell = GetView(); |
| if ( pViewShell && pViewShell->ISA(SmViewShell) ) |
| { |
| // Terminate possible InPlace mode |
| bCallBase = !pViewShell->Escape(); |
| } |
| if ( bCallBase ) |
| Window::KeyInput( rKEvt ); |
| } |
| else |
| { |
| // Timer neu starten, um den Handler (auch bei laengeren Eingaben) |
| // moeglichst nur einmal am Ende aufzurufen. |
| aCursorMoveTimer.Start(); |
| |
| DBG_ASSERT( pEditView, "EditView missing (NULL pointer)" ); |
| if (!pEditView) |
| CreateEditView(); |
| if ( !pEditView->PostKeyEvent(rKEvt) ) |
| { |
| SmViewShell *pView = GetView(); |
| if ( pView && !pView->KeyInput(rKEvt) ) |
| { |
| /* fuert bei F1 (Hilfe) zum Zerstoeren von this! */ |
| Flush(); |
| if ( aModifyTimer.IsActive() ) |
| aModifyTimer.Stop(); |
| Window::KeyInput(rKEvt); |
| } |
| else |
| { |
| //SFX hat evtl. Slot an der View gecallt und dabei (wg. Hack |
| //im SFX) den Focus auf die View gesetzt |
| SfxViewShell* pVShell = GetView(); |
| if ( pVShell && pVShell->ISA(SmViewShell) && |
| ((SmViewShell*)pVShell)->GetGraphicWindow().HasFocus() ) |
| { |
| GrabFocus(); |
| } |
| } |
| } |
| else |
| { |
| // have doc-shell modified only for formula input/change and not |
| // cursor travelling and such things... |
| SmDocShell *pDocShell = GetDoc(); |
| if (pDocShell) |
| pDocShell->SetModified( GetEditEngine()->IsModified() ); |
| |
| aModifyTimer.Start(); |
| } |
| |
| InvalidateSlots(); |
| } |
| } |
| |
| void SmEditWindow::Paint(const Rectangle& rRect) |
| { |
| if (!pEditView) |
| CreateEditView(); |
| pEditView->Paint(rRect); |
| } |
| |
| void SmEditWindow::CreateEditView() |
| { |
| EditEngine *pEditEngine = GetEditEngine(); |
| |
| //! pEditEngine and pEditView may be 0. |
| //! For example when the program is used by the document-converter |
| if (!pEditView && pEditEngine) |
| { |
| pEditView = new EditView( pEditEngine, this ); |
| pEditEngine->InsertView( pEditView ); |
| |
| if (!pVScrollBar) |
| pVScrollBar = new ScrollBar(this, WinBits(WB_VSCROLL)); |
| if (!pHScrollBar) |
| pHScrollBar = new ScrollBar(this, WinBits(WB_HSCROLL)); |
| if (!pScrollBox) |
| pScrollBox = new ScrollBarBox(this); |
| pVScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl)); |
| pHScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl)); |
| pVScrollBar->EnableDrag( sal_True ); |
| pHScrollBar->EnableDrag( sal_True ); |
| |
| pEditView->SetOutputArea(AdjustScrollBars()); |
| |
| ESelection eSelection; |
| |
| pEditView->SetSelection(eSelection); |
| Update(); |
| pEditView->ShowCursor(sal_True, sal_True); |
| |
| pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) ); |
| SetPointer(pEditView->GetPointer()); |
| |
| SetScrollBarRanges(); |
| } |
| } |
| |
| |
| IMPL_LINK( SmEditWindow, EditStatusHdl, EditStatus *, EMPTYARG /*pStat*/ ) |
| { |
| if (!pEditView) |
| return 1; |
| else |
| { |
| Resize(); |
| return 0; |
| } |
| } |
| |
| IMPL_LINK_INLINE_START( SmEditWindow, ScrollHdl, ScrollBar *, EMPTYARG /*pScrollBar*/ ) |
| { |
| DBG_ASSERT(pEditView, "EditView missing"); |
| if (pEditView) |
| { |
| pEditView->SetVisArea(Rectangle(Point(pHScrollBar->GetThumbPos(), |
| pVScrollBar->GetThumbPos()), |
| pEditView->GetVisArea().GetSize())); |
| pEditView->Invalidate(); |
| } |
| return 0; |
| } |
| IMPL_LINK_INLINE_END( SmEditWindow, ScrollHdl, ScrollBar *, pScrollBar ) |
| |
| Rectangle SmEditWindow::AdjustScrollBars() |
| { |
| const Size aOut( GetOutputSizePixel() ); |
| Point aPoint; |
| Rectangle aRect( aPoint, aOut ); |
| |
| if (pVScrollBar && pHScrollBar && pScrollBox) |
| { |
| const long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize(); |
| Point aPt( aRect.TopRight() ); aPt.X() -= nTmp -1L; |
| pVScrollBar->SetPosSizePixel( aPt, Size(nTmp, aOut.Height() - nTmp)); |
| |
| aPt = aRect.BottomLeft(); aPt.Y() -= nTmp - 1L; |
| pHScrollBar->SetPosSizePixel( aPt, Size(aOut.Width() - nTmp, nTmp)); |
| |
| aPt.X() = pHScrollBar->GetSizePixel().Width(); |
| aPt.Y() = pVScrollBar->GetSizePixel().Height(); |
| pScrollBox->SetPosSizePixel(aPt, Size(nTmp, nTmp )); |
| |
| aRect.Right() = aPt.X() - 2; |
| aRect.Bottom() = aPt.Y() - 2; |
| } |
| return aRect; |
| } |
| |
| void SmEditWindow::SetScrollBarRanges() |
| { |
| // Extra-Methode, nicht InitScrollBars, da auch fuer EditEngine-Events. |
| EditEngine *pEditEngine = GetEditEngine(); |
| if (pVScrollBar && pHScrollBar && pEditEngine && pEditView) |
| { |
| long nTmp = pEditEngine->GetTextHeight(); |
| pVScrollBar->SetRange(Range(0, nTmp)); |
| pVScrollBar->SetThumbPos(pEditView->GetVisArea().Top()); |
| |
| nTmp = pEditEngine->GetPaperSize().Width(); |
| pHScrollBar->SetRange(Range(0,nTmp)); |
| pHScrollBar->SetThumbPos(pEditView->GetVisArea().Left()); |
| } |
| } |
| |
| void SmEditWindow::InitScrollBars() |
| { |
| if (pVScrollBar && pHScrollBar && pScrollBox && pEditView) |
| { |
| const Size aOut( pEditView->GetOutputArea().GetSize() ); |
| pVScrollBar->SetVisibleSize(aOut.Height()); |
| pVScrollBar->SetPageSize(aOut.Height() * 8 / 10); |
| pVScrollBar->SetLineSize(aOut.Height() * 2 / 10); |
| |
| pHScrollBar->SetVisibleSize(aOut.Width()); |
| pHScrollBar->SetPageSize(aOut.Width() * 8 / 10); |
| pHScrollBar->SetLineSize(SCROLL_LINE ); |
| |
| SetScrollBarRanges(); |
| |
| pVScrollBar->Show(); |
| pHScrollBar->Show(); |
| pScrollBox->Show(); |
| } |
| } |
| |
| |
| String SmEditWindow::GetText() const |
| { |
| String aText; |
| EditEngine *pEditEngine = const_cast< SmEditWindow* >(this)->GetEditEngine(); |
| DBG_ASSERT( pEditEngine, "EditEngine missing" ); |
| if (pEditEngine) |
| aText = pEditEngine->GetText( LINEEND_LF ); |
| return aText; |
| } |
| |
| |
| void SmEditWindow::SetText(const XubString& rText) |
| { |
| EditEngine *pEditEngine = GetEditEngine(); |
| DBG_ASSERT( pEditEngine, "EditEngine missing" ); |
| if (pEditEngine && !pEditEngine->IsModified()) |
| { |
| if (!pEditView) |
| CreateEditView(); |
| |
| ESelection eSelection = pEditView->GetSelection(); |
| |
| pEditEngine->SetText(rText); |
| pEditEngine->ClearModifyFlag(); |
| |
| //! Hier die Timer neu zu starten verhindert, dass die Handler fuer andere |
| //! (im Augenblick nicht mehr aktive) Math Tasks aufgerufen werden. |
| aModifyTimer.Start(); |
| aCursorMoveTimer.Start(); |
| |
| pEditView->SetSelection(eSelection); |
| } |
| } |
| |
| |
| void SmEditWindow::GetFocus() |
| { |
| Window::GetFocus(); |
| |
| if (xAccessible.is()) |
| { |
| // Note: will implicitly send the AccessibleStateType::FOCUSED event |
| ::accessibility::AccessibleTextHelper *pHelper = pAccessible->GetTextHelper(); |
| if (pHelper) |
| pHelper->SetFocus( sal_True ); |
| } |
| |
| if (!pEditView) |
| CreateEditView(); |
| EditEngine *pEditEngine = GetEditEngine(); |
| if (pEditEngine) |
| pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) ); |
| } |
| |
| |
| void SmEditWindow::LoseFocus() |
| { |
| EditEngine *pEditEngine = GetEditEngine(); |
| if (pEditEngine) |
| pEditEngine->SetStatusEventHdl( Link() ); |
| |
| Window::LoseFocus(); |
| |
| if (xAccessible.is()) |
| { |
| // Note: will implicitly send the AccessibleStateType::FOCUSED event |
| ::accessibility::AccessibleTextHelper *pHelper = pAccessible->GetTextHelper(); |
| if (pHelper) |
| pHelper->SetFocus( sal_False ); |
| } |
| } |
| |
| |
| sal_Bool SmEditWindow::IsAllSelected() const |
| { |
| sal_Bool bRes = sal_False; |
| EditEngine *pEditEngine = ((SmEditWindow *) this)->GetEditEngine(); |
| DBG_ASSERT( pEditView, "NULL pointer" ); |
| DBG_ASSERT( pEditEngine, "NULL pointer" ); |
| if (pEditEngine && pEditView) |
| { |
| ESelection eSelection( pEditView->GetSelection() ); |
| sal_Int32 nParaCnt = pEditEngine->GetParagraphCount(); |
| if (!(nParaCnt - 1)) |
| { |
| String Text( pEditEngine->GetText( LINEEND_LF ) ); |
| bRes = !eSelection.nStartPos && (eSelection.nEndPos == Text.Len () - 1); |
| } |
| else |
| { |
| bRes = !eSelection.nStartPara && (eSelection.nEndPara == nParaCnt - 1); |
| } |
| } |
| return bRes; |
| } |
| |
| void SmEditWindow::SelectAll() |
| { |
| DBG_ASSERT( pEditView, "NULL pointer" ); |
| if (pEditView) |
| { |
| // 0xFFFF as last two parameters refers to the end of the text |
| pEditView->SetSelection( ESelection( 0, 0, 0xFFFF, 0xFFFF ) ); |
| } |
| } |
| |
| void SmEditWindow::InsertCommand(sal_uInt16 nCommand) |
| { |
| DBG_ASSERT( pEditView, "EditView missing" ); |
| if (pEditView) |
| { |
| //Anfang der Selektion merken und hinterher den Cursor daraufsetzen. Nur so |
| //macht das SelNextMark() Sinn. |
| ESelection aSelection = pEditView->GetSelection(); |
| aSelection.nEndPos = aSelection.nStartPos; |
| aSelection.nEndPara = aSelection.nStartPara; |
| |
| DBG_ASSERT( pEditView, "NULL pointer" ); |
| String aText = String(SmResId(nCommand)); |
| pEditView->InsertText(aText); |
| |
| if (HasMark(aText)) |
| { // set selection to next mark |
| pEditView->SetSelection(aSelection); |
| SelNextMark(); |
| } |
| else |
| { // set selection after inserted text |
| aSelection.nEndPos = aSelection.nEndPos + sal::static_int_cast< xub_StrLen >(aText.Len()); |
| aSelection.nStartPos = aSelection.nEndPos; |
| pEditView->SetSelection(aSelection); |
| } |
| |
| aModifyTimer.Start(); |
| aCursorMoveTimer.Start(); |
| |
| GrabFocus(); |
| } |
| } |
| |
| void SmEditWindow::MarkError(const Point &rPos) |
| { |
| DBG_ASSERT( pEditView, "EditView missing" ); |
| if (pEditView) |
| { |
| const xub_StrLen nCol = sal::static_int_cast< xub_StrLen >(rPos.X()); |
| const sal_uInt16 nRow = sal::static_int_cast< sal_uInt16 >(rPos.Y() - 1); |
| |
| pEditView->SetSelection(ESelection(nRow, nCol - 1, nRow, nCol)); |
| GrabFocus(); |
| } |
| } |
| |
| void SmEditWindow::SelNextMark() |
| { |
| EditEngine *pEditEngine = GetEditEngine(); |
| DBG_ASSERT( pEditView, "NULL pointer" ); |
| DBG_ASSERT( pEditEngine, "NULL pointer" ); |
| if (pEditEngine && pEditView) |
| { |
| ESelection eSelection = pEditView->GetSelection(); |
| sal_uInt16 Pos = eSelection.nEndPos; |
| String aMark (C2S("<?>")); |
| String aText; |
| sal_uInt16 nCounts = pEditEngine->GetParagraphCount(); |
| |
| while (eSelection.nEndPara < nCounts) |
| { |
| aText = pEditEngine->GetText( eSelection.nEndPara ); |
| Pos = aText.Search(aMark, Pos); |
| |
| if (Pos != STRING_NOTFOUND) |
| { |
| pEditView->SetSelection(ESelection (eSelection.nEndPara, Pos, eSelection.nEndPara, Pos + 3)); |
| break; |
| } |
| |
| Pos = 0; |
| eSelection.nEndPara++; |
| } |
| } |
| } |
| |
| void SmEditWindow::SelPrevMark() |
| { |
| EditEngine *pEditEngine = GetEditEngine(); |
| DBG_ASSERT( pEditEngine, "NULL pointer" ); |
| DBG_ASSERT( pEditView, "NULL pointer" ); |
| if (pEditEngine && pEditView) |
| { |
| ESelection eSelection = pEditView->GetSelection(); |
| sal_uInt16 Pos = STRING_NOTFOUND; |
| xub_StrLen Max = eSelection.nStartPos; |
| String Text( pEditEngine->GetText( eSelection.nStartPara ) ); |
| String aMark (C2S("<?>")); |
| sal_uInt16 nCounts = pEditEngine->GetParagraphCount(); |
| |
| do |
| { |
| sal_uInt16 Fnd = Text.Search(aMark, 0); |
| |
| while ((Fnd < Max) && (Fnd != STRING_NOTFOUND)) |
| { |
| Pos = Fnd; |
| Fnd = Text.Search(aMark, Fnd + 1); |
| } |
| |
| if (Pos == STRING_NOTFOUND) |
| { |
| eSelection.nStartPara--; |
| Text = pEditEngine->GetText( eSelection.nStartPara ); |
| Max = Text.Len(); |
| } |
| } |
| while ((eSelection.nStartPara < nCounts) && |
| (Pos == STRING_NOTFOUND)); |
| |
| if (Pos != STRING_NOTFOUND) |
| { |
| pEditView->SetSelection(ESelection (eSelection.nStartPara, Pos, eSelection.nStartPara, Pos + 3)); |
| } |
| } |
| } |
| |
| sal_Bool SmEditWindow::HasMark(const String& rText) const |
| // returns true iff 'rText' contains a mark |
| { |
| return rText.SearchAscii("<?>", 0) != STRING_NOTFOUND; |
| } |
| |
| void SmEditWindow::MouseMove(const MouseEvent &rEvt) |
| { |
| if (pEditView) |
| pEditView->MouseMove(rEvt); |
| } |
| |
| sal_Int8 SmEditWindow::AcceptDrop( const AcceptDropEvent& /*rEvt*/ ) |
| { |
| return pEditView ? /*pEditView->QueryDrop( rEvt )*/DND_ACTION_NONE: DND_ACTION_NONE; |
| } |
| |
| sal_Int8 SmEditWindow::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ ) |
| { |
| return pEditView ? /*pEditView->Drop( rEvt )*/DND_ACTION_NONE : DND_ACTION_NONE; |
| } |
| |
| ESelection SmEditWindow::GetSelection() const |
| { |
| // pointer may be 0 when reloading a document and the old view |
| // was already destroyed |
| //(DBG_ASSERT( pEditView, "NULL pointer" ); |
| ESelection eSel; |
| if (pEditView) |
| eSel = pEditView->GetSelection(); |
| return eSel; |
| } |
| |
| void SmEditWindow::SetSelection(const ESelection &rSel) |
| { |
| DBG_ASSERT( pEditView, "NULL pointer" ); |
| if (pEditView) |
| pEditView->SetSelection(rSel); |
| InvalidateSlots(); |
| } |
| |
| sal_Bool SmEditWindow::IsEmpty() const |
| { |
| EditEngine *pEditEngine = ((SmEditWindow *) this)->GetEditEngine(); |
| sal_Bool bEmpty = sal::static_int_cast< sal_Bool >( |
| pEditEngine ? pEditEngine->GetTextLen() == 0 : sal_False); |
| return bEmpty; |
| } |
| |
| sal_Bool SmEditWindow::IsSelected() const |
| { |
| return pEditView ? pEditView->HasSelection() : sal_False; |
| } |
| |
| |
| void SmEditWindow::UpdateStatus( bool bSetDocModified ) |
| { |
| SmModule *pMod = SM_MOD(); |
| if (pMod && pMod->GetConfig()->IsAutoRedraw()) |
| Flush(); |
| if ( bSetDocModified ) |
| GetDoc()->SetModified( sal_True ); |
| } |
| |
| void SmEditWindow::Cut() |
| { |
| DBG_ASSERT( pEditView, "EditView missing" ); |
| if (pEditView) |
| { |
| pEditView->Cut(); |
| UpdateStatus( sal_True ); |
| } |
| } |
| |
| void SmEditWindow::Copy() |
| { |
| DBG_ASSERT( pEditView, "EditView missing" ); |
| if (pEditView) |
| pEditView->Copy(); |
| } |
| |
| void SmEditWindow::Paste() |
| { |
| DBG_ASSERT( pEditView, "EditView missing" ); |
| if (pEditView) |
| { |
| pEditView->Paste(); |
| UpdateStatus( sal_True ); |
| } |
| } |
| |
| void SmEditWindow::Delete() |
| { |
| DBG_ASSERT( pEditView, "EditView missing" ); |
| if (pEditView) |
| { |
| pEditView->DeleteSelected(); |
| UpdateStatus( sal_True ); |
| } |
| } |
| |
| void SmEditWindow::InsertText(const String& Text) |
| { |
| DBG_ASSERT( pEditView, "EditView missing" ); |
| if (pEditView) |
| { |
| pEditView->InsertText(Text); |
| aModifyTimer.Start(); |
| aCursorMoveTimer.Start(); |
| } |
| } |
| |
| void SmEditWindow::Flush() |
| { |
| EditEngine *pEditEngine = GetEditEngine(); |
| if (pEditEngine && pEditEngine->IsModified()) |
| { |
| pEditEngine->ClearModifyFlag(); |
| SmViewShell *pViewSh = rCmdBox.GetView(); |
| if (pViewSh) |
| { |
| pViewSh->GetViewFrame()->GetDispatcher()->Execute( |
| SID_TEXT, SFX_CALLMODE_STANDARD, |
| new SfxStringItem(SID_TEXT, GetText()), 0L); |
| } |
| } |
| |
| if (aCursorMoveTimer.IsActive()) |
| { |
| aCursorMoveTimer.Stop(); |
| // ggf noch die (neue) FormulaCursor Position setzen |
| CursorMoveTimerHdl(&aCursorMoveTimer); |
| } |
| } |
| |
| |
| void SmEditWindow::DeleteEditView( SmViewShell & /*rView*/ ) |
| { |
| if (pEditView) |
| { |
| EditEngine *pEditEngine = pEditView->GetEditEngine(); |
| if (pEditEngine) |
| { |
| pEditEngine->SetStatusEventHdl( Link() ); |
| pEditEngine->RemoveView( pEditView ); |
| } |
| delete pEditView; |
| pEditView = 0; |
| } |
| } |
| |
| |
| uno::Reference< XAccessible > SmEditWindow::CreateAccessible() |
| { |
| if (!pAccessible) |
| { |
| pAccessible = new SmEditAccessible( this ); |
| xAccessible = pAccessible; |
| pAccessible->Init(); |
| } |
| return xAccessible; |
| } |
| |