/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "impedit.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace com::sun::star; using namespace com::sun::star::uno; using namespace com::sun::star::beans; // static LanguageType EditView::CheckLanguage( const OUString &rText, const Reference< linguistic2::XSpellChecker1 >& xSpell, const Reference< linguistic2::XLanguageGuessing >& xLangGuess, bool bIsParaText ) { LanguageType nLang = LANGUAGE_NONE; if (bIsParaText) // check longer texts with language-guessing... { if (!xLangGuess.is()) return nLang; LanguageTag aGuessTag( xLangGuess->guessPrimaryLanguage( rText, 0, rText.getLength()) ); // If the result from language guessing does not provide a 'Country' // part, try to get it by looking up the locale setting of the office, // "Tools/Options - Language Settings - Languages: Locale setting", if // the language matches. if ( aGuessTag.getCountry().isEmpty() ) { const LanguageTag& rAppLocaleTag = Application::GetSettings().GetLanguageTag(); if (rAppLocaleTag.getLanguage() == aGuessTag.getLanguage()) nLang = rAppLocaleTag.getLanguageType(); } if (nLang == LANGUAGE_NONE) // language not found by looking up the system language... nLang = aGuessTag.makeFallback().getLanguageType(); // best known locale match if (nLang == LANGUAGE_SYSTEM) nLang = Application::GetSettings().GetLanguageTag().getLanguageType(); if (nLang == LANGUAGE_DONTKNOW) nLang = LANGUAGE_NONE; } else // check single word { if (!xSpell.is()) return nLang; // build list of languages to check LanguageType aLangList[4]; const AllSettings& rSettings = Application::GetSettings(); SvtLinguOptions aLinguOpt; SvtLinguConfig().GetOptions( aLinguOpt ); // The default document language from "Tools/Options - Language Settings - Languages: Western" aLangList[0] = MsLangId::resolveSystemLanguageByScriptType( aLinguOpt.nDefaultLanguage, css::i18n::ScriptType::LATIN); // The one from "Tools/Options - Language Settings - Languages: User interface" aLangList[1] = rSettings.GetUILanguageTag().getLanguageType(); // The one from "Tools/Options - Language Settings - Languages: Locale setting" aLangList[2] = rSettings.GetLanguageTag().getLanguageType(); // en-US aLangList[3] = LANGUAGE_ENGLISH_US; #ifdef DEBUG lang::Locale a0( LanguageTag::convertToLocale( aLangList[0] ) ); lang::Locale a1( LanguageTag::convertToLocale( aLangList[1] ) ); lang::Locale a2( LanguageTag::convertToLocale( aLangList[2] ) ); lang::Locale a3( LanguageTag::convertToLocale( aLangList[3] ) ); #endif sal_Int32 const nCount = SAL_N_ELEMENTS(aLangList); for (sal_Int32 i = 0; i < nCount; i++) { LanguageType nTmpLang = aLangList[i]; if (nTmpLang != LANGUAGE_NONE && nTmpLang != LANGUAGE_DONTKNOW) { if (xSpell->hasLanguage( static_cast(nTmpLang) ) && xSpell->isValid( rText, static_cast(nTmpLang), Sequence< PropertyValue >() )) { nLang = nTmpLang; break; } } } } return nLang; } // class EditViewCallbacks EditViewCallbacks::~EditViewCallbacks() { } // class EditView EditView::EditView( EditEngine* pEng, vcl::Window* pWindow ) { pImpEditView.reset( new ImpEditView( this, pEng, pWindow ) ); } EditView::~EditView() { } void EditView::setEditViewCallbacks(const EditViewCallbacks* pEditViewCallbacks) { pImpEditView->setEditViewCallbacks(pEditViewCallbacks); } const EditViewCallbacks* EditView::getEditViewCallbacks() const { return pImpEditView->getEditViewCallbacks(); } ImpEditEngine* EditView::GetImpEditEngine() const { return pImpEditView->pEditEngine->pImpEditEngine.get(); } EditEngine* EditView::GetEditEngine() const { return pImpEditView->pEditEngine; } tools::Rectangle EditView::GetInvalidateRect() const { if ( !pImpEditView->DoInvalidateMore() ) return pImpEditView->aOutArea; else { tools::Rectangle aRect( pImpEditView->aOutArea ); long nMore = pImpEditView->GetWindow()->PixelToLogic( Size( pImpEditView->GetInvalidateMore(), 0 ) ).Width(); aRect.AdjustLeft( -nMore ); aRect.AdjustRight(nMore ); aRect.AdjustTop( -nMore ); aRect.AdjustBottom(nMore ); return aRect; } } void EditView::InvalidateWindow(const tools::Rectangle& rClipRect) { if (const EditViewCallbacks* pEditViewCallbacks = pImpEditView->getEditViewCallbacks()) { // do not invalidate and trigger a global repaint, but forward // the need for change to the applied EditViewCallback, can e.g. // be used to visualize the active edit text in an OverlayObject pEditViewCallbacks->EditViewInvalidate(rClipRect); } else { // classic mode: invalidate and trigger full repaint // of the changed area GetWindow()->Invalidate(rClipRect); } } void EditView::InvalidateOtherViewWindows( const tools::Rectangle& rInvRect ) { if (comphelper::LibreOfficeKit::isActive()) { for (auto& pWin : pImpEditView->aOutWindowSet) { if (pWin) pWin->Invalidate( rInvRect ); } } } void EditView::Invalidate() { const tools::Rectangle& rInvRect = GetInvalidateRect(); pImpEditView->InvalidateAtWindow(rInvRect); InvalidateOtherViewWindows(rInvRect); } void EditView::SetReadOnly( bool bReadOnly ) { pImpEditView->bReadOnly = bReadOnly; } bool EditView::IsReadOnly() const { return pImpEditView->bReadOnly; } void EditView::SetSelection( const ESelection& rESel ) { // If someone has just left an empty attribute, and then the outliner manipulates the // selection, call the CursorMoved method so that empty attributes get cleaned up. if ( !HasSelection() ) { // tdf#113591 Get node from EditDoc, as the selection might have a pointer to an // already deleted node. const ContentNode* pNode = pImpEditView->pEditEngine->GetEditDoc().GetEndPaM().GetNode(); pImpEditView->pEditEngine->CursorMoved( pNode ); } EditSelection aNewSelection( pImpEditView->pEditEngine->pImpEditEngine->ConvertSelection( rESel.nStartPara, rESel.nStartPos, rESel.nEndPara, rESel.nEndPos ) ); // If the selection is manipulated after a KeyInput: pImpEditView->pEditEngine->CheckIdleFormatter(); // Selection may not start/end at an invisible paragraph: const ParaPortion* pPortion = pImpEditView->pEditEngine->FindParaPortion( aNewSelection.Min().GetNode() ); if ( !pPortion->IsVisible() ) { pPortion = pImpEditView->pEditEngine->GetPrevVisPortion( pPortion ); ContentNode* pNode = pPortion ? pPortion->GetNode() : pImpEditView->pEditEngine->GetEditDoc().GetObject( 0 ); aNewSelection.Min() = EditPaM( pNode, pNode->Len() ); } pPortion = pImpEditView->pEditEngine->FindParaPortion( aNewSelection.Max().GetNode() ); if ( !pPortion->IsVisible() ) { pPortion = pImpEditView->pEditEngine->GetPrevVisPortion( pPortion ); ContentNode* pNode = pPortion ? pPortion->GetNode() : pImpEditView->pEditEngine->GetEditDoc().GetObject( 0 ); aNewSelection.Max() = EditPaM( pNode, pNode->Len() ); } pImpEditView->DrawSelectionXOR(); pImpEditView->SetEditSelection( aNewSelection ); pImpEditView->DrawSelectionXOR(); bool bGotoCursor = pImpEditView->DoAutoScroll(); ShowCursor( bGotoCursor ); } ESelection EditView::GetSelection() const { ESelection aSelection; aSelection.nStartPara = pImpEditView->pEditEngine->GetEditDoc().GetPos( pImpEditView->GetEditSelection().Min().GetNode() ); aSelection.nEndPara = pImpEditView->pEditEngine->GetEditDoc().GetPos( pImpEditView->GetEditSelection().Max().GetNode() ); aSelection.nStartPos = pImpEditView->GetEditSelection().Min().GetIndex(); aSelection.nEndPos = pImpEditView->GetEditSelection().Max().GetIndex(); return aSelection; } bool EditView::HasSelection() const { return pImpEditView->HasSelection(); } void EditView::DeleteSelected() { pImpEditView->DeleteSelected(); } SvtScriptType EditView::GetSelectedScriptType() const { return pImpEditView->pEditEngine->GetScriptType( pImpEditView->GetEditSelection() ); } void EditView::GetSelectionRectangles(std::vector& rLogicRects) const { return pImpEditView->GetSelectionRectangles(pImpEditView->GetEditSelection(), rLogicRects); } void EditView::Paint( const tools::Rectangle& rRect, OutputDevice* pTargetDevice ) { pImpEditView->pEditEngine->pImpEditEngine->Paint( pImpEditView.get(), rRect, pTargetDevice ); } void EditView::SetEditEngine( EditEngine* pEditEng ) { pImpEditView->pEditEngine = pEditEng; EditSelection aStartSel = pImpEditView->pEditEngine->GetEditDoc().GetStartPaM(); pImpEditView->SetEditSelection( aStartSel ); } void EditView::SetWindow( vcl::Window* pWin ) { pImpEditView->pOutWin = pWin; pImpEditView->pEditEngine->pImpEditEngine->GetSelEngine().Reset(); } vcl::Window* EditView::GetWindow() const { return pImpEditView->pOutWin; } bool EditView::HasOtherViewWindow( vcl::Window* pWin ) { OutWindowSet& rOutWindowSet = pImpEditView->aOutWindowSet; auto found = std::find(rOutWindowSet.begin(), rOutWindowSet.end(), pWin); return (found != rOutWindowSet.end()); } bool EditView::AddOtherViewWindow( vcl::Window* pWin ) { if (HasOtherViewWindow(pWin)) return false; pImpEditView->aOutWindowSet.emplace_back(pWin); return true; } bool EditView::RemoveOtherViewWindow( vcl::Window* pWin ) { OutWindowSet& rOutWindowSet = pImpEditView->aOutWindowSet; auto found = std::find(rOutWindowSet.begin(), rOutWindowSet.end(), pWin); if (found == rOutWindowSet.end()) return false; rOutWindowSet.erase(found); return true; } void EditView::SetVisArea( const tools::Rectangle& rRect ) { pImpEditView->SetVisDocStartPos( rRect.TopLeft() ); } const tools::Rectangle& EditView::GetVisArea() const { // Change return value to Rectangle in next incompatible build !!! static tools::Rectangle aRect; aRect = pImpEditView->GetVisDocArea(); return aRect; } void EditView::SetOutputArea( const tools::Rectangle& rRect ) { pImpEditView->SetOutputArea( rRect ); // the rest here only if it is an API call: pImpEditView->CalcAnchorPoint(); if ( pImpEditView->pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() ) pImpEditView->RecalcOutputArea(); pImpEditView->ShowCursor( false, false ); } const tools::Rectangle& EditView::GetOutputArea() const { return pImpEditView->GetOutputArea(); } PointerStyle EditView::GetPointer() const { return pImpEditView->GetPointer(); } vcl::Cursor* EditView::GetCursor() const { return pImpEditView->pCursor.get(); } void EditView::InsertText( const OUString& rStr, bool bSelect ) { EditEngine* pEE = pImpEditView->pEditEngine; pImpEditView->DrawSelectionXOR(); EditPaM aPaM1; if ( bSelect ) { EditSelection aTmpSel( pImpEditView->GetEditSelection() ); aTmpSel.Adjust( pEE->GetEditDoc() ); aPaM1 = aTmpSel.Min(); } pEE->UndoActionStart( EDITUNDO_INSERT ); EditPaM aPaM2( pEE->InsertText( pImpEditView->GetEditSelection(), rStr ) ); pEE->UndoActionEnd(); if ( bSelect ) { DBG_ASSERT( !aPaM1.DbgIsBuggy( pEE->GetEditDoc() ), "Insert: PaM broken" ); pImpEditView->SetEditSelection( EditSelection( aPaM1, aPaM2 ) ); } else pImpEditView->SetEditSelection( EditSelection( aPaM2, aPaM2 ) ); pEE->FormatAndUpdate( this ); } bool EditView::PostKeyEvent( const KeyEvent& rKeyEvent, vcl::Window const * pFrameWin ) { return pImpEditView->PostKeyEvent( rKeyEvent, pFrameWin ); } bool EditView::MouseButtonUp( const MouseEvent& rMouseEvent ) { return pImpEditView->MouseButtonUp( rMouseEvent ); } void EditView::ReleaseMouse() { return pImpEditView->ReleaseMouse(); } bool EditView::MouseButtonDown( const MouseEvent& rMouseEvent ) { return pImpEditView->MouseButtonDown( rMouseEvent ); } bool EditView::MouseMove( const MouseEvent& rMouseEvent ) { return pImpEditView->MouseMove( rMouseEvent ); } void EditView::Command( const CommandEvent& rCEvt ) { pImpEditView->Command( rCEvt ); } void EditView::ShowCursor( bool bGotoCursor, bool bForceVisCursor, bool bActivate ) { if ( pImpEditView->pEditEngine->HasView( this ) ) { // The control word is more important: if ( !pImpEditView->DoAutoScroll() ) bGotoCursor = false; pImpEditView->ShowCursor( bGotoCursor, bForceVisCursor ); if (pImpEditView->mpViewShell && !bActivate) { OString aPayload = OString::boolean(true); pImpEditView->mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, aPayload.getStr()); pImpEditView->mpViewShell->NotifyOtherViews(LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", aPayload); } } } void EditView::HideCursor(bool bDeactivate) { pImpEditView->GetCursor()->Hide(); if (pImpEditView->mpViewShell && !bDeactivate) { OString aPayload = OString::boolean(false); pImpEditView->mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, aPayload.getStr()); pImpEditView->mpViewShell->NotifyOtherViews(LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", aPayload); } } Pair EditView::Scroll( long ndX, long ndY, ScrollRangeCheck nRangeCheck ) { return pImpEditView->Scroll( ndX, ndY, nRangeCheck ); } const SfxItemSet& EditView::GetEmptyItemSet() { return pImpEditView->pEditEngine->GetEmptyItemSet(); } void EditView::SetAttribs( const SfxItemSet& rSet ) { DBG_ASSERT( !pImpEditView->aEditSelection.IsInvalid(), "Blind Selection in ...." ); pImpEditView->DrawSelectionXOR(); pImpEditView->pEditEngine->SetAttribs( pImpEditView->GetEditSelection(), rSet, SetAttribsMode::WholeWord ); pImpEditView->pEditEngine->FormatAndUpdate( this ); } void EditView::RemoveAttribsKeepLanguages( bool bRemoveParaAttribs ) { pImpEditView->DrawSelectionXOR(); pImpEditView->pEditEngine->UndoActionStart( EDITUNDO_RESETATTRIBS ); EditSelection aSelection( pImpEditView->GetEditSelection() ); for (sal_uInt16 nWID = EE_ITEMS_START; nWID <= EE_ITEMS_END; ++nWID) { bool bIsLang = EE_CHAR_LANGUAGE == nWID || EE_CHAR_LANGUAGE_CJK == nWID || EE_CHAR_LANGUAGE_CTL == nWID; if (!bIsLang) pImpEditView->pEditEngine->RemoveCharAttribs( aSelection, bRemoveParaAttribs, nWID ); } pImpEditView->pEditEngine->UndoActionEnd(); pImpEditView->pEditEngine->FormatAndUpdate( this ); } void EditView::RemoveAttribs( bool bRemoveParaAttribs, sal_uInt16 nWhich ) { pImpEditView->DrawSelectionXOR(); pImpEditView->pEditEngine->UndoActionStart( EDITUNDO_RESETATTRIBS ); pImpEditView->pEditEngine->RemoveCharAttribs( pImpEditView->GetEditSelection(), bRemoveParaAttribs, nWhich ); pImpEditView->pEditEngine->UndoActionEnd(); pImpEditView->pEditEngine->FormatAndUpdate( this ); } void EditView::RemoveCharAttribs( sal_Int32 nPara, sal_uInt16 nWhich ) { pImpEditView->pEditEngine->UndoActionStart( EDITUNDO_RESETATTRIBS ); pImpEditView->pEditEngine->RemoveCharAttribs( nPara, nWhich ); pImpEditView->pEditEngine->UndoActionEnd(); pImpEditView->pEditEngine->FormatAndUpdate( this ); } SfxItemSet EditView::GetAttribs() { DBG_ASSERT( !pImpEditView->aEditSelection.IsInvalid(), "Blind Selection in ...." ); return pImpEditView->pEditEngine->pImpEditEngine->GetAttribs( pImpEditView->GetEditSelection() ); } void EditView::Undo() { pImpEditView->pEditEngine->Undo( this ); } void EditView::Redo() { pImpEditView->pEditEngine->Redo( this ); } ErrCode EditView::Read( SvStream& rInput, EETextFormat eFormat, SvKeyValueIterator* pHTTPHeaderAttrs ) { EditSelection aOldSel( pImpEditView->GetEditSelection() ); pImpEditView->DrawSelectionXOR(); pImpEditView->pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_READ ); EditPaM aEndPaM = pImpEditView->pEditEngine->pImpEditEngine->Read( rInput, "", eFormat, aOldSel, pHTTPHeaderAttrs ); pImpEditView->pEditEngine->pImpEditEngine->UndoActionEnd(); EditSelection aNewSel( aEndPaM, aEndPaM ); pImpEditView->SetEditSelection( aNewSel ); bool bGotoCursor = pImpEditView->DoAutoScroll(); ShowCursor( bGotoCursor ); return rInput.GetError(); } void EditView::Cut() { Reference aClipBoard(GetWindow()->GetClipboard()); pImpEditView->CutCopy( aClipBoard, true ); } css::uno::Reference< css::datatransfer::XTransferable > EditView::GetTransferable() { uno::Reference< datatransfer::XTransferable > xData = GetEditEngine()->CreateTransferable( pImpEditView->GetEditSelection() ); return xData; } void EditView::Copy() { Reference aClipBoard(GetWindow()->GetClipboard()); pImpEditView->CutCopy( aClipBoard, false ); } void EditView::Paste() { Reference aClipBoard(GetWindow()->GetClipboard()); pImpEditView->Paste( aClipBoard ); } void EditView::PasteSpecial() { Reference aClipBoard(GetWindow()->GetClipboard()); pImpEditView->Paste(aClipBoard, true ); } Point EditView::GetWindowPosTopLeft( sal_Int32 nParagraph ) { Point aDocPos( pImpEditView->pEditEngine->GetDocPosTopLeft( nParagraph ) ); return pImpEditView->GetWindowPos( aDocPos ); } void EditView::SetSelectionMode( EESelectionMode eMode ) { pImpEditView->SetSelectionMode( eMode ); } OUString EditView::GetSelected() { return pImpEditView->pEditEngine->pImpEditEngine->GetSelected( pImpEditView->GetEditSelection() ); } void EditView::MoveParagraphs( Range aParagraphs, sal_Int32 nNewPos ) { pImpEditView->pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_MOVEPARAS ); pImpEditView->pEditEngine->pImpEditEngine->MoveParagraphs( aParagraphs, nNewPos, this ); pImpEditView->pEditEngine->pImpEditEngine->UndoActionEnd(); } void EditView::MoveParagraphs( long nDiff ) { ESelection aSel = GetSelection(); Range aRange( aSel.nStartPara, aSel.nEndPara ); aRange.Justify(); long nDest = ( nDiff > 0 ? aRange.Max() : aRange.Min() ) + nDiff; if ( nDiff > 0 ) nDest++; DBG_ASSERT( ( nDest >= 0 ) && ( nDest <= pImpEditView->pEditEngine->GetParagraphCount() ), "MoveParagraphs - wrong Parameters!" ); MoveParagraphs( aRange, sal::static_int_cast< sal_Int32 >( nDest ) ); } void EditView::SetBackgroundColor( const Color& rColor ) { pImpEditView->SetBackgroundColor( rColor ); } Color const & EditView::GetBackgroundColor() const { return pImpEditView->GetBackgroundColor(); } void EditView::RegisterViewShell(OutlinerViewShell* pViewShell) { pImpEditView->RegisterViewShell(pViewShell); } void EditView::RegisterOtherShell(OutlinerViewShell* pOtherShell) { pImpEditView->RegisterOtherShell(pOtherShell); } void EditView::SetControlWord( EVControlBits nWord ) { pImpEditView->nControl = nWord; } EVControlBits EditView::GetControlWord() const { return pImpEditView->nControl; } std::unique_ptr EditView::CreateTextObject() { return pImpEditView->pEditEngine->pImpEditEngine->CreateTextObject( pImpEditView->GetEditSelection() ); } void EditView::InsertText( const EditTextObject& rTextObject ) { pImpEditView->DrawSelectionXOR(); pImpEditView->pEditEngine->UndoActionStart( EDITUNDO_INSERT ); EditSelection aTextSel( pImpEditView->pEditEngine->InsertText( rTextObject, pImpEditView->GetEditSelection() ) ); pImpEditView->pEditEngine->UndoActionEnd(); aTextSel.Min() = aTextSel.Max(); // Selection not retained. pImpEditView->SetEditSelection( aTextSel ); pImpEditView->pEditEngine->FormatAndUpdate( this ); } void EditView::InsertText( css::uno::Reference< css::datatransfer::XTransferable > const & xDataObj, const OUString& rBaseURL, bool bUseSpecial ) { pImpEditView->pEditEngine->UndoActionStart( EDITUNDO_INSERT ); pImpEditView->DeleteSelected(); EditSelection aTextSel = pImpEditView->pEditEngine->InsertText(xDataObj, rBaseURL, pImpEditView->GetEditSelection().Max(), bUseSpecial); pImpEditView->pEditEngine->UndoActionEnd(); aTextSel.Min() = aTextSel.Max(); // Selection not retained. pImpEditView->SetEditSelection( aTextSel ); pImpEditView->pEditEngine->FormatAndUpdate( this ); } void EditView::SetEditEngineUpdateMode( bool bUpdate ) { pImpEditView->pEditEngine->pImpEditEngine->SetUpdateMode( bUpdate, this ); } void EditView::ForceUpdate() { pImpEditView->pEditEngine->pImpEditEngine->SetUpdateMode( true, this, true ); } SfxStyleSheet* EditView::GetStyleSheet() { EditSelection aSel( pImpEditView->GetEditSelection() ); aSel.Adjust( pImpEditView->pEditEngine->GetEditDoc() ); sal_Int32 nStartPara = pImpEditView->pEditEngine->GetEditDoc().GetPos( aSel.Min().GetNode() ); sal_Int32 nEndPara = pImpEditView->pEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() ); SfxStyleSheet* pStyle = nullptr; for ( sal_Int32 n = nStartPara; n <= nEndPara; n++ ) { SfxStyleSheet* pTmpStyle = pImpEditView->pEditEngine->GetStyleSheet( n ); if ( ( n != nStartPara ) && ( pStyle != pTmpStyle ) ) return nullptr; // Not unique. pStyle = pTmpStyle; } return pStyle; } const SfxStyleSheet* EditView::GetStyleSheet() const { return const_cast< EditView* >( this )->GetStyleSheet(); } bool EditView::IsInsertMode() const { return pImpEditView->IsInsertMode(); } void EditView::SetInsertMode( bool bInsert ) { pImpEditView->SetInsertMode( bInsert ); } void EditView::SetAnchorMode( EEAnchorMode eMode ) { pImpEditView->SetAnchorMode( eMode ); } EEAnchorMode EditView::GetAnchorMode() const { return pImpEditView->GetAnchorMode(); } void EditView::TransliterateText( TransliterationFlags nTransliterationMode ) { EditSelection aOldSel( pImpEditView->GetEditSelection() ); EditSelection aNewSel = pImpEditView->pEditEngine->TransliterateText( pImpEditView->GetEditSelection(), nTransliterationMode ); if ( aNewSel != aOldSel ) { pImpEditView->DrawSelectionXOR(); pImpEditView->SetEditSelection( aNewSel ); pImpEditView->DrawSelectionXOR(); } } void EditView::CompleteAutoCorrect( vcl::Window const * pFrameWin ) { if ( !HasSelection() && pImpEditView->pEditEngine->pImpEditEngine->GetStatus().DoAutoCorrect() ) { pImpEditView->DrawSelectionXOR(); EditSelection aSel = pImpEditView->GetEditSelection(); aSel = pImpEditView->pEditEngine->EndOfWord( aSel.Max() ); aSel = pImpEditView->pEditEngine->pImpEditEngine->AutoCorrect( aSel, 0, !IsInsertMode(), pFrameWin ); pImpEditView->SetEditSelection( aSel ); if ( pImpEditView->pEditEngine->IsModified() ) pImpEditView->pEditEngine->FormatAndUpdate( this ); } } EESpellState EditView::StartSpeller( bool bMultipleDoc ) { if ( !pImpEditView->pEditEngine->pImpEditEngine->GetSpeller().is() ) return EESpellState::NoSpeller; return pImpEditView->pEditEngine->pImpEditEngine->Spell( this, bMultipleDoc ); } EESpellState EditView::StartThesaurus() { if ( !pImpEditView->pEditEngine->pImpEditEngine->GetSpeller().is() ) return EESpellState::NoSpeller; return pImpEditView->pEditEngine->pImpEditEngine->StartThesaurus( this ); } void EditView::StartTextConversion( LanguageType nSrcLang, LanguageType nDestLang, const vcl::Font *pDestFont, sal_Int32 nOptions, bool bIsInteractive, bool bMultipleDoc ) { pImpEditView->pEditEngine->pImpEditEngine->Convert( this, nSrcLang, nDestLang, pDestFont, nOptions, bIsInteractive, bMultipleDoc ); } sal_Int32 EditView::StartSearchAndReplace( const SvxSearchItem& rSearchItem ) { return pImpEditView->pEditEngine->pImpEditEngine->StartSearchAndReplace( this, rSearchItem ); } bool EditView::IsCursorAtWrongSpelledWord() { bool bIsWrong = false; if ( !HasSelection() ) { EditPaM aPaM = pImpEditView->GetEditSelection().Max(); bIsWrong = pImpEditView->IsWrongSpelledWord( aPaM, false/*bMarkIfWrong*/ ); } return bIsWrong; } bool EditView::IsWrongSpelledWordAtPos( const Point& rPosPixel, bool bMarkIfWrong ) { Point aPos ( pImpEditView->GetWindow()->PixelToLogic( rPosPixel ) ); aPos = pImpEditView->GetDocPos( aPos ); EditPaM aPaM = pImpEditView->pEditEngine->GetPaM(aPos, false); return pImpEditView->IsWrongSpelledWord( aPaM , bMarkIfWrong ); } void EditView::ExecuteSpellPopup( const Point& rPosPixel, Link const * pCallBack ) { Point aPos ( pImpEditView->GetWindow()->PixelToLogic( rPosPixel ) ); aPos = pImpEditView->GetDocPos( aPos ); EditPaM aPaM = pImpEditView->pEditEngine->GetPaM(aPos, false); Reference< linguistic2::XSpellChecker1 > xSpeller( pImpEditView->pEditEngine->pImpEditEngine->GetSpeller() ); ESelection aOldSel = GetSelection(); if ( xSpeller.is() && pImpEditView->IsWrongSpelledWord( aPaM, true ) ) { VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "editeng/ui/spellmenu.ui", ""); VclPtr aPopupMenu(aBuilder.get_menu("menu")); const sal_uInt16 nAutoCorrId = aPopupMenu->GetItemId("autocorrect"); PopupMenu *pAutoMenu = aPopupMenu->GetPopupMenu(nAutoCorrId); const sal_uInt16 nInsertId = aPopupMenu->GetItemId("insert"); PopupMenu *pInsertMenu = aPopupMenu->GetPopupMenu(nInsertId); // add word to user-dictionaries pInsertMenu->SetMenuFlags( MenuFlags::NoAutoMnemonics ); //! necessary to retrieve the correct dictionary names later const sal_uInt16 nAddId = aPopupMenu->GetItemId("add"); const sal_uInt16 nIgnoreId = aPopupMenu->GetItemId("ignore"); const sal_uInt16 nCheckId = aPopupMenu->GetItemId("check"); const sal_uInt16 nAutoCorrectDlgId = aPopupMenu->GetItemId("autocorrectdlg"); EditPaM aPaM2( aPaM ); aPaM2.SetIndex( aPaM2.GetIndex()+1 ); // Are there any replace suggestions? OUString aSelected( GetSelected() ); // restrict the maximal number of suggestions displayed // in the context menu. // Note: That could of course be done by clipping the // resulting sequence but the current third party // implementations result differs greatly if the number of // suggestions to be returned gets changed. Statistically // it gets much better if told to return e.g. only 7 strings // than returning e.g. 16 suggestions and using only the // first 7. Thus we hand down the value to use to that // implementation here by providing an additional parameter. Sequence< PropertyValue > aPropVals(1); PropertyValue &rVal = aPropVals.getArray()[0]; rVal.Name = UPN_MAX_NUMBER_OF_SUGGESTIONS; rVal.Value <<= sal_Int16(7); // Are there any replace suggestions? Reference< linguistic2::XSpellAlternatives > xSpellAlt = xSpeller->spell( aSelected, static_cast(pImpEditView->pEditEngine->pImpEditEngine->GetLanguage( aPaM2 )), aPropVals ); Reference< linguistic2::XLanguageGuessing > xLangGuesser( EditDLL::Get().GetGlobalData()->GetLanguageGuesser() ); // check if text might belong to a different language... LanguageType nGuessLangWord = LANGUAGE_NONE; LanguageType nGuessLangPara = LANGUAGE_NONE; if (xSpellAlt.is() && xLangGuesser.is()) { OUString aParaText; ContentNode *pNode = aPaM.GetNode(); if (pNode) { aParaText = pNode->GetString(); } else { OSL_FAIL( "content node is NULL" ); } nGuessLangWord = CheckLanguage( xSpellAlt->getWord(), xSpeller, xLangGuesser, false ); nGuessLangPara = CheckLanguage( aParaText, xSpeller, xLangGuesser, true ); } if (nGuessLangWord != LANGUAGE_NONE || nGuessLangPara != LANGUAGE_NONE) { // make sure LANGUAGE_NONE gets not used as menu entry if (nGuessLangWord == LANGUAGE_NONE) nGuessLangWord = nGuessLangPara; if (nGuessLangPara == LANGUAGE_NONE) nGuessLangPara = nGuessLangWord; aPopupMenu->InsertSeparator(); OUString aTmpWord( SvtLanguageTable::GetLanguageString( nGuessLangWord ) ); OUString aTmpPara( SvtLanguageTable::GetLanguageString( nGuessLangPara ) ); OUString aWordStr( EditResId( RID_STR_WORD ) ); aWordStr = aWordStr.replaceFirst( "%x", aTmpWord ); OUString aParaStr( EditResId( RID_STR_PARAGRAPH ) ); aParaStr = aParaStr.replaceFirst( "%x", aTmpPara ); aPopupMenu->InsertItem( MN_WORDLANGUAGE, aWordStr ); aPopupMenu->SetHelpId( MN_WORDLANGUAGE, HID_EDITENG_SPELLER_WORDLANGUAGE ); aPopupMenu->InsertItem( MN_PARALANGUAGE, aParaStr ); aPopupMenu->SetHelpId( MN_PARALANGUAGE, HID_EDITENG_SPELLER_PARALANGUAGE ); } // ## Create mnemonics here aPopupMenu->CreateAutoMnemonics(); aPopupMenu->SetMenuFlags(aPopupMenu->GetMenuFlags() | MenuFlags::NoAutoMnemonics); // Replace suggestions... Sequence< OUString > aAlt; if (xSpellAlt.is()) aAlt = xSpellAlt->getAlternatives(); const OUString *pAlt = aAlt.getConstArray(); sal_uInt16 nWords = static_cast(aAlt.getLength()); if ( nWords ) { for ( sal_uInt16 nW = 0; nW < nWords; nW++ ) { OUString aAlternate( pAlt[nW] ); aPopupMenu->InsertItem( MN_ALTSTART+nW, aAlternate, MenuItemBits::NONE, OString(), nW ); pAutoMenu->InsertItem( MN_AUTOSTART+nW, aAlternate, MenuItemBits::NONE, OString(), nW ); } aPopupMenu->InsertSeparator(OString(), nWords); } else aPopupMenu->RemoveItem(nAutoCorrId); // delete? SvtLinguConfig aCfg; Reference< linguistic2::XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() ); Sequence< Reference< linguistic2::XDictionary > > aDics; if (xDicList.is()) { const Reference< linguistic2::XDictionary > *pDic = nullptr; // add the default positive dictionary to dic-list (if not already done). // This is to ensure that there is at least one dictionary to which // words could be added. uno::Reference< linguistic2::XDictionary > xDic( LinguMgr::GetStandardDic() ); if (xDic.is()) xDic->setActive( true ); aDics = xDicList->getDictionaries(); pDic = aDics.getConstArray(); LanguageType nCheckedLanguage = pImpEditView->pEditEngine->pImpEditEngine->GetLanguage( aPaM2 ); sal_uInt16 nDicCount = static_cast(aDics.getLength()); for (sal_uInt16 i = 0; i < nDicCount; i++) { uno::Reference< linguistic2::XDictionary > xDicTmp( pDic[i], uno::UNO_QUERY ); if (!xDicTmp.is() || LinguMgr::GetIgnoreAllList() == xDicTmp) continue; uno::Reference< frame::XStorable > xStor( xDicTmp, uno::UNO_QUERY ); LanguageType nActLanguage = LanguageTag( xDicTmp->getLocale() ).getLanguageType(); if( xDicTmp->isActive() && xDicTmp->getDictionaryType() != linguistic2::DictionaryType_NEGATIVE && (nCheckedLanguage == nActLanguage || LANGUAGE_NONE == nActLanguage ) && (!xStor.is() || !xStor->isReadonly()) ) { // the extra 1 is because of the (possible) external // linguistic entry above sal_uInt16 nPos = MN_DICTSTART + i; pInsertMenu->InsertItem( nPos, xDicTmp->getName() ); aDicNameSingle = xDicTmp->getName(); uno::Reference< lang::XServiceInfo > xSvcInfo( xDicTmp, uno::UNO_QUERY ); if (xSvcInfo.is()) { OUString aDictionaryImageUrl( aCfg.GetSpellAndGrammarContextDictionaryImage( xSvcInfo->getImplementationName()) ); if (!aDictionaryImageUrl.isEmpty() ) { Image aImage( aDictionaryImageUrl ); pInsertMenu->SetItemImage( nPos, aImage ); } } } } } if (pInsertMenu->GetItemCount() != 1) aPopupMenu->EnableItem(nAddId, false); if (pInsertMenu->GetItemCount() < 2) aPopupMenu->EnableItem(nInsertId, false); aPopupMenu->RemoveDisabledEntries( true, true ); tools::Rectangle aTempRect = pImpEditView->pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM, GetCursorFlags::TextOnly ); Point aScreenPos = pImpEditView->GetWindowPos( aTempRect.TopLeft() ); aScreenPos = pImpEditView->GetWindow()->OutputToScreenPixel( aScreenPos ); aTempRect = pImpEditView->GetWindow()->LogicToPixel( tools::Rectangle(aScreenPos, aTempRect.GetSize() )); //tdf#106123 store and restore the EditPaM around the menu Execute //because the loss of focus in the current editeng causes writer //annotations to save their contents, making the pContent of the //current EditPams invalid EPaM aP = pImpEditView->pEditEngine->pImpEditEngine->CreateEPaM(aPaM); EPaM aP2 = pImpEditView->pEditEngine->pImpEditEngine->CreateEPaM(aPaM2); if (comphelper::LibreOfficeKit::isActive()) aPopupMenu->SetLOKNotifier(SfxViewShell::Current()); sal_uInt16 nId = aPopupMenu->Execute(pImpEditView->GetWindow(), aTempRect, PopupMenuFlags::NoMouseUpClose); aPaM2 = pImpEditView->pEditEngine->pImpEditEngine->CreateEditPaM(aP2); aPaM = pImpEditView->pEditEngine->pImpEditEngine->CreateEditPaM(aP); if (nId == nIgnoreId) { OUString aWord = pImpEditView->SpellIgnoreWord(); if ( pCallBack ) { SpellCallbackInfo aInf( SpellCallbackCommand::IGNOREWORD, aWord ); pCallBack->Call( aInf ); } SetSelection( aOldSel ); } else if ( ( nId == MN_WORDLANGUAGE ) || ( nId == MN_PARALANGUAGE ) ) { LanguageType nLangToUse = (nId == MN_WORDLANGUAGE) ? nGuessLangWord : nGuessLangPara; SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( nLangToUse ); SfxItemSet aAttrs = GetEditEngine()->GetEmptyItemSet(); if (nScriptType == SvtScriptType::LATIN) aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE ) ); if (nScriptType == SvtScriptType::COMPLEX) aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CTL ) ); if (nScriptType == SvtScriptType::ASIAN) aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CJK ) ); if ( nId == MN_PARALANGUAGE ) { ESelection aSel = GetSelection(); aSel.nStartPos = 0; aSel.nEndPos = EE_TEXTPOS_ALL; SetSelection( aSel ); } SetAttribs( aAttrs ); pImpEditView->pEditEngine->pImpEditEngine->StartOnlineSpellTimer(); if ( pCallBack ) { SpellCallbackInfo aInf( ( nId == MN_WORDLANGUAGE ) ? SpellCallbackCommand::WORDLANGUAGE : SpellCallbackCommand::PARALANGUAGE ); pCallBack->Call( aInf ); } SetSelection( aOldSel ); } else if (nId == nCheckId) { if ( !pCallBack ) { // Set Cursor before word... EditPaM aCursor = pImpEditView->GetEditSelection().Min(); pImpEditView->DrawSelectionXOR(); pImpEditView->SetEditSelection( EditSelection( aCursor, aCursor ) ); pImpEditView->DrawSelectionXOR(); // Crashes when no SfxApp pImpEditView->pEditEngine->pImpEditEngine->Spell( this, false ); } else { SpellCallbackInfo aInf( SpellCallbackCommand::STARTSPELLDLG, OUString() ); pCallBack->Call( aInf ); } } else if (nId == nAutoCorrectDlgId && pCallBack) { SpellCallbackInfo aInf( SpellCallbackCommand::AUTOCORRECT_OPTIONS, OUString() ); pCallBack->Call( aInf ); } else if ( nId >= MN_DICTSTART || nId == nAddId) { OUString aDicName; if (nId >= MN_DICTSTART) aDicName = pInsertMenu->GetItemText(nId); else aDicName = aDicNameSingle; uno::Reference< linguistic2::XDictionary > xDic; if (xDicList.is()) xDic = xDicList->getDictionaryByName( aDicName ); if (xDic.is()) xDic->add( aSelected, false, OUString() ); // save modified user-dictionary if it is persistent Reference< frame::XStorable > xSavDic( xDic, UNO_QUERY ); if (xSavDic.is()) xSavDic->store(); aPaM.GetNode()->GetWrongList()->ResetInvalidRange(0, aPaM.GetNode()->Len()); pImpEditView->pEditEngine->pImpEditEngine->StartOnlineSpellTimer(); if ( pCallBack ) { SpellCallbackInfo aInf( SpellCallbackCommand::ADDTODICTIONARY, aSelected ); pCallBack->Call( aInf ); } SetSelection( aOldSel ); } else if ( nId >= MN_AUTOSTART ) { DBG_ASSERT(nId - MN_AUTOSTART < aAlt.getLength(), "index out of range"); OUString aWord = pAlt[nId - MN_AUTOSTART]; SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect(); if ( pAutoCorrect ) pAutoCorrect->PutText( aSelected, aWord, pImpEditView->pEditEngine->pImpEditEngine->GetLanguage( aPaM2 ) ); InsertText( aWord ); } else if ( nId >= MN_ALTSTART ) // Replace { DBG_ASSERT(nId - MN_ALTSTART < aAlt.getLength(), "index out of range"); OUString aWord = pAlt[nId - MN_ALTSTART]; InsertText( aWord ); } else { SetSelection( aOldSel ); } } } void EditView::SelectCurrentWord( sal_Int16 nWordType ) { EditSelection aCurSel( pImpEditView->GetEditSelection() ); pImpEditView->DrawSelectionXOR(); aCurSel = pImpEditView->pEditEngine->SelectWord(aCurSel.Max(), nWordType); pImpEditView->SetEditSelection( aCurSel ); pImpEditView->DrawSelectionXOR(); ShowCursor( true, false ); } void EditView::InsertParaBreak() { pImpEditView->pEditEngine->UndoActionStart(EDITUNDO_INSERT); pImpEditView->DeleteSelected(); EditPaM aPaM(pImpEditView->pEditEngine->InsertParaBreak(pImpEditView->GetEditSelection())); pImpEditView->pEditEngine->UndoActionEnd(); pImpEditView->SetEditSelection(EditSelection(aPaM, aPaM)); pImpEditView->pEditEngine->FormatAndUpdate(this); } void EditView::InsertField( const SvxFieldItem& rFld ) { EditEngine* pEE = pImpEditView->pEditEngine; pImpEditView->DrawSelectionXOR(); pEE->UndoActionStart( EDITUNDO_INSERT ); EditPaM aPaM( pEE->InsertField( pImpEditView->GetEditSelection(), rFld ) ); pEE->UndoActionEnd(); pImpEditView->SetEditSelection( EditSelection( aPaM, aPaM ) ); pEE->UpdateFields(); pEE->FormatAndUpdate( this ); } const SvxFieldItem* EditView::GetFieldUnderMousePointer() const { sal_Int32 nPara; sal_Int32 nPos; return GetFieldUnderMousePointer( nPara, nPos ); } const SvxFieldItem* EditView::GetField( const Point& rPos, sal_Int32* pPara, sal_Int32* pPos ) const { return pImpEditView->GetField( rPos, pPara, pPos ); } const SvxFieldItem* EditView::GetFieldUnderMousePointer( sal_Int32& nPara, sal_Int32& nPos ) const { Point aPos = pImpEditView->GetWindow()->GetPointerPosPixel(); aPos = pImpEditView->GetWindow()->PixelToLogic( aPos ); return GetField( aPos, &nPara, &nPos ); } const SvxFieldItem* EditView::GetFieldAtSelection() const { EditSelection aSel( pImpEditView->GetEditSelection() ); aSel.Adjust( pImpEditView->pEditEngine->GetEditDoc() ); // Only when cursor is in font of field, no selection, // or only selecting field if ( ( aSel.Min().GetNode() == aSel.Max().GetNode() ) && ( ( aSel.Max().GetIndex() == aSel.Min().GetIndex() ) || ( aSel.Max().GetIndex() == aSel.Min().GetIndex()+1 ) ) ) { EditPaM aPaM = aSel.Min(); const CharAttribList::AttribsType& rAttrs = aPaM.GetNode()->GetCharAttribs().GetAttribs(); const sal_Int32 nXPos = aPaM.GetIndex(); for (size_t nAttr = rAttrs.size(); nAttr; ) { const EditCharAttrib& rAttr = *rAttrs[--nAttr].get(); if (rAttr.GetStart() == nXPos) if (rAttr.Which() == EE_FEATURE_FIELD) { DBG_ASSERT(dynamic_cast(rAttr.GetItem() ) != nullptr, "No FieldItem..."); return static_cast(rAttr.GetItem()); } } } return nullptr; } void EditView::SetInvalidateMore( sal_uInt16 nPixel ) { pImpEditView->SetInvalidateMore( nPixel ); } sal_uInt16 EditView::GetInvalidateMore() const { return pImpEditView->GetInvalidateMore(); } static void ChangeFontSizeImpl( EditView* pEditView, bool bGrow, const ESelection& rSel, const FontList* pFontList ) { pEditView->SetSelection( rSel ); SfxItemSet aSet( pEditView->GetAttribs() ); if( EditView::ChangeFontSize( bGrow, aSet, pFontList ) ) { SfxItemSet aNewSet( pEditView->GetEmptyItemSet() ); aNewSet.Put( aSet.Get( EE_CHAR_FONTHEIGHT ) ); aNewSet.Put( aSet.Get( EE_CHAR_FONTHEIGHT_CJK ) ); aNewSet.Put( aSet.Get( EE_CHAR_FONTHEIGHT_CTL ) ); pEditView->SetAttribs( aNewSet ); } } void EditView::ChangeFontSize( bool bGrow, const FontList* pFontList ) { EditEngine& rEditEngine = *pImpEditView->pEditEngine; ESelection aSel( GetSelection() ); ESelection aOldSelection( aSel ); aSel.Adjust(); if( !aSel.HasRange() ) { aSel = rEditEngine.GetWord( aSel, css::i18n::WordType::DICTIONARY_WORD ); } if( aSel.HasRange() ) { for( sal_Int32 nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ ) { std::vector aPortions; rEditEngine.GetPortions( nPara, aPortions ); if( aPortions.empty() ) aPortions.push_back( rEditEngine.GetTextLen(nPara) ); const sal_Int32 nBeginPos = (nPara == aSel.nStartPara) ? aSel.nStartPos : 0; const sal_Int32 nEndPos = (nPara == aSel.nEndPara) ? aSel.nEndPos : EE_TEXTPOS_ALL; for ( size_t nPos = 0; nPos < aPortions.size(); ++nPos ) { sal_Int32 nPortionEnd = aPortions[ nPos ]; sal_Int32 nPortionStart = nPos > 0 ? aPortions[ nPos - 1 ] : 0; if( (nPortionEnd < nBeginPos) || (nPortionStart > nEndPos) ) continue; if( nPortionStart < nBeginPos ) nPortionStart = nBeginPos; if( nPortionEnd > nEndPos ) nPortionEnd = nEndPos; if( nPortionStart == nPortionEnd ) continue; ESelection aPortionSel( nPara, nPortionStart, nPara, nPortionEnd ); ChangeFontSizeImpl( this, bGrow, aPortionSel, pFontList ); } } } else { ChangeFontSizeImpl( this, bGrow, aSel, pFontList ); } SetSelection( aOldSelection ); } bool EditView::ChangeFontSize( bool bGrow, SfxItemSet& rSet, const FontList* pFontList ) { if (!pFontList) return false; static const sal_uInt16 gFontSizeWichMap[] = { EE_CHAR_FONTHEIGHT, EE_CHAR_FONTHEIGHT_CJK, EE_CHAR_FONTHEIGHT_CTL, 0 }; const SvxFontItem& rFontItem = rSet.Get(EE_CHAR_FONTINFO); bool bRet = false; const sal_uInt16* pWhich = gFontSizeWichMap; while( *pWhich ) { SvxFontHeightItem aFontHeightItem( static_cast(rSet.Get( *pWhich )) ); long nHeight = aFontHeightItem.GetHeight(); const MapUnit eUnit = rSet.GetPool()->GetMetric( *pWhich ); nHeight = OutputDevice::LogicToLogic(nHeight * 10, eUnit, MapUnit::MapPoint); FontMetric aFontMetric = pFontList->Get( rFontItem.GetFamilyName(), rFontItem.GetStyleName() ); const sal_IntPtr* pAry = pFontList->GetSizeAry( aFontMetric ); if( bGrow ) { while( *pAry ) { if( *pAry > nHeight ) { nHeight = *pAry; break; } pAry++; } if( *pAry == 0 ) { nHeight += (nHeight + 5) / 10; if( nHeight > 9999 ) nHeight = 9999; } } else if( *pAry ) { bool bFound = false; if( *pAry < nHeight ) { pAry++; while( *pAry ) { if( *pAry >= nHeight ) { nHeight = pAry[-1]; bFound = true; break; } pAry++; } } if( !bFound ) { nHeight -= (nHeight + 5) / 10; if( nHeight < 2 ) nHeight = 2; } } if( (nHeight >= 2) && (nHeight <= 9999 ) ) { nHeight = OutputDevice::LogicToLogic( nHeight, MapUnit::MapPoint, eUnit ) / 10; if( nHeight != static_cast(aFontHeightItem.GetHeight()) ) { aFontHeightItem.SetHeight( nHeight ); rSet.Put( aFontHeightItem.CloneSetWhich(*pWhich) ); bRet = true; } } pWhich++; } return bRet; } OUString EditView::GetSurroundingText() const { EditSelection aSel( pImpEditView->GetEditSelection() ); aSel.Adjust( pImpEditView->pEditEngine->GetEditDoc() ); if( HasSelection() ) { OUString aStr = pImpEditView->pEditEngine->GetSelected(aSel); // Stop reconversion if the selected text includes a line break. if ( aStr.indexOf( 0x0A ) == -1 ) return aStr; else return OUString(); } else { aSel.Min().SetIndex( 0 ); aSel.Max().SetIndex( aSel.Max().GetNode()->Len() ); return pImpEditView->pEditEngine->GetSelected(aSel); } } Selection EditView::GetSurroundingTextSelection() const { ESelection aSelection( GetSelection() ); aSelection.Adjust(); if( HasSelection() ) { EditSelection aSel( pImpEditView->GetEditSelection() ); aSel.Adjust( pImpEditView->pEditEngine->GetEditDoc() ); OUString aStr = pImpEditView->pEditEngine->GetSelected(aSel); // Stop reconversion if the selected text includes a line break. if ( aStr.indexOf( 0x0A ) == -1 ) return Selection( 0, aSelection.nEndPos - aSelection.nStartPos ); else return Selection( 0, 0 ); } else { return Selection( aSelection.nStartPos, aSelection.nEndPos ); } } void EditView::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark) { Point aDocPos(pImpEditView->GetDocPos(rPosition)); EditPaM aPaM = pImpEditView->pEditEngine->GetPaM(aDocPos); EditSelection aSelection(pImpEditView->GetEditSelection()); // Explicitly create or delete the selection. if (bClearMark) { pImpEditView->DeselectAll(); aSelection = pImpEditView->GetEditSelection(); } else pImpEditView->CreateAnchor(); if (bPoint) aSelection.Max() = aPaM; else aSelection.Min() = aPaM; if (pImpEditView->GetEditSelection().Min() != aSelection.Min()) pImpEditView->pEditEngine->CursorMoved(pImpEditView->GetEditSelection().Min().GetNode()); pImpEditView->DrawSelectionXOR(aSelection); if (pImpEditView->GetEditSelection() != aSelection) pImpEditView->SetEditSelection(aSelection); ShowCursor(/*bGotoCursor=*/false); } void EditView::DrawSelectionXOR(OutlinerViewShell* pOtherShell) { pImpEditView->RegisterOtherShell(pOtherShell); pImpEditView->DrawSelectionXOR(); pImpEditView->RegisterOtherShell(nullptr); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */