/* -*- 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 .
*/
SmViewShell *pViewSh = SmGetActiveView(); if (pViewSh)
{
pViewSh->GetViewFrame().GetBindings().Invalidate(SID_TEXT); if ( SfxObjectCreateMode::EMBEDDED == GetCreateMode() )
{ // have SwOleClient::FormatChanged() to align the modified formula properly // even if the visible area does not change (e.g. when formula text changes from // "{a over b + c} over d" to "d over {a over b + c}"
SfxGetpApp()->NotifyEvent(SfxEventHint( SfxEventHintId::VisAreaChanged, GlobalEventConfig::GetEventName(GlobalEventId::VISAREACHANGED), this));
mnModifyCount++; //! see comment for SID_GRAPHIC_SM in SmDocShell::GetState
// don't use SmGetActiveView since the view shell might not be active (0 pointer) // if for example the Basic Macro dialog currently has the focus. Thus:
SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); while (pFrm)
{
pFrm->GetBindings().Invalidate(SID_GRAPHIC_SM);
pFrm = SfxViewFrame::GetNext( *pFrm, this );
}
}
void SmDocShell::Parse()
{
mpTree.reset();
ReplaceBadChars();
mpTree = maParser->Parse(maText);
mnModifyCount++; //! see comment for SID_GRAPHIC_SM in SmDocShell::GetState
SetFormulaArranged( false );
InvalidateCursor();
maUsedSymbols = maParser->GetUsedSymbols();
}
void SmDocShell::ArrangeFormula()
{ if (mbFormulaArranged) return;
// Only for the duration of the existence of this object the correct settings // at the printer are guaranteed!
SmPrinterAccess aPrtAcc(*this);
OutputDevice* pOutDev = aPrtAcc.GetRefDev();
// if necessary get another OutputDevice for which we format if (!pOutDev)
{ if (SmViewShell *pView = SmGetActiveView())
pOutDev = &pView->GetGraphicWidget().GetDrawingArea()->get_ref_device(); else
{
pOutDev = &SmModule::get()->GetDefaultVirtualDev();
pOutDev->SetMapMode( MapMode(SmMapUnit()) );
}
}
OSL_ENSURE(pOutDev->GetMapMode().GetMapUnit() == SmMapUnit(), "Sm : wrong MapMode");
// We want the device to always be LTR, we handle RTL formulas ourselves. bool bOldRTL = pOutDev->IsRTLEnabled();
pOutDev->EnableRTL(false);
// For RTL formulas, we want the brackets to be mirrored. bool bRTL = GetFormat().IsRightToLeft();
pOutDev->SetLayoutMode(bRTL ? vcl::text::ComplexTextLayoutFlags::BiDiRtl
: vcl::text::ComplexTextLayoutFlags::Default);
// Numbers should not be converted, for now.
pOutDev->SetDigitLanguage( LANGUAGE_ENGLISH );
mpTree->Arrange(*pOutDev, rFormat);
pOutDev->EnableRTL(bOldRTL);
pOutDev->Pop();
SetFormulaArranged(true);
// invalidate accessible text
maAccText.clear();
}
EditEngine& SmDocShell::GetEditEngine()
{ if (!mpEditEngine)
{ //! //! see also SmEditWindow::DataChanged ! //!
mpEditEngineItemPool = EditEngine::CreatePool();
SmEditEngine::setSmItemPool(mpEditEngineItemPool.get(), maLinguOptions);
mpEditEngine.reset( new SmEditEngine( mpEditEngineItemPool.get() ) );
mpEditEngine->EraseVirtualDevice();
// set initial text if the document already has some... // (may be the case when reloading a doc)
OUString aTxt( GetText() ); if (!aTxt.isEmpty())
mpEditEngine->SetText( aTxt );
mpEditEngine->ClearModifyFlag();
} return *mpEditEngine;
}
void SmDocShell::DrawFormula(OutputDevice &rDev, Point &rPosition, bool bDrawSelection)
{ if (!mpTree)
Parse();
OSL_ENSURE(mpTree, "Sm : NULL pointer");
ArrangeFormula();
bool bRTL = GetFormat().IsRightToLeft();
// Problem: What happens to WYSIWYG? While we're active inplace, we don't have a reference // device and aren't aligned to that either. So now there can be a difference between the // VisArea (i.e. the size within the client) and the current size. // Idea: The difference could be adapted with SmNod::SetSize (no long-term solution)
Point aPosition(rPosition); if (bRTL && rDev.GetOutDevType() != OUTDEV_WINDOW)
aPosition.AdjustX(GetSize().Width()
- maFormat.GetDistance(DIS_LEFTSPACE)
- maFormat.GetDistance(DIS_RIGHTSPACE));
//! in case of high contrast-mode (accessibility option!) //! the draw mode needs to be set to default, because when embedding //! Math for example in Calc in "a over b" the fraction bar may not //! be visible else. More generally: the FillColor may have been changed.
DrawModeFlags nOldDrawMode = DrawModeFlags::Default; bool bRestoreDrawMode = false; if (OUTDEV_WINDOW == rDev.GetOutDevType() &&
rDev.GetOwnerWindow()->GetSettings().GetStyleSettings().GetHighContrastMode())
{
nOldDrawMode = rDev.GetDrawMode();
rDev.SetDrawMode( DrawModeFlags::Default );
bRestoreDrawMode = true;
}
// We want the device to always be LTR, we handle RTL formulas ourselves. bool bOldRTL = rDev.IsRTLEnabled(); if (rDev.GetOutDevType() == OUTDEV_WINDOW)
rDev.EnableRTL(bRTL); else
rDev.EnableRTL(false);
auto nLayoutFlags = vcl::text::ComplexTextLayoutFlags::Default; if (bRTL)
{ // For RTL formulas, we want the brackets to be mirrored.
nLayoutFlags |= vcl::text::ComplexTextLayoutFlags::BiDiRtl; if (rDev.GetOutDevType() == OUTDEV_WINDOW)
nLayoutFlags |= vcl::text::ComplexTextLayoutFlags::TextOriginLeft;
}
rDev.SetLayoutMode(nLayoutFlags);
// Numbers should not be converted, for now.
rDev.SetDigitLanguage( LANGUAGE_ENGLISH );
//Set selection if any if(mpCursor && bDrawSelection){
mpCursor->AnnotateSelection();
SmSelectionDrawingVisitor(rDev, mpTree.get(), aPosition);
}
//Drawing using visitor
SmDrawingVisitor(rDev, aPosition, mpTree.get(), GetFormat());
rDev.EnableRTL(bOldRTL);
rDev.Pop();
if (bRestoreDrawMode)
rDev.SetDrawMode( nOldDrawMode );
}
Size SmDocShell::GetSize()
{
Size aRet;
if (!mpTree)
Parse();
if (mpTree)
{
ArrangeFormula();
aRet = mpTree->GetSize();
SmPrinterAccess::SmPrinterAccess( SmDocShell &rDocShell )
{
pPrinter = rDocShell.GetPrt(); if ( pPrinter )
{
pPrinter->Push( vcl::PushFlags::MAPMODE ); if ( SfxObjectCreateMode::EMBEDDED == rDocShell.GetCreateMode() )
{ // if it is an embedded object (without its own printer) // we change the MapMode temporarily. //!If it is a document with its own printer the MapMode should //!be set correct (once) elsewhere(!), in order to avoid numerous //!superfluous pushing and popping of the MapMode when using //!this class.
pRefDev->Push( vcl::PushFlags::MAPMODE ); if ( SfxObjectCreateMode::EMBEDDED != rDocShell.GetCreateMode() ) return;
// if it is an embedded object (without its own printer) // we change the MapMode temporarily. //!If it is a document with its own printer the MapMode should //!be set correct (once) elsewhere(!), in order to avoid numerous //!superfluous pushing and popping of the MapMode when using //!this class.
SmPrinterAccess::~SmPrinterAccess()
{ if ( pPrinter )
pPrinter->Pop(); if ( pRefDev && pRefDev != pPrinter )
pRefDev->Pop();
}
Printer* SmDocShell::GetPrt()
{ if (SfxObjectCreateMode::EMBEDDED == GetCreateMode())
{ // Normally the server provides the printer. But if it doesn't provide one (e.g. because // there is no connection) it still can be the case that we know the printer because it // has been passed on by the server in OnDocumentPrinterChanged and being kept temporarily.
Printer* pPrt = GetDocumentPrinter(); if (!pPrt && mpTmpPrinter)
pPrt = mpTmpPrinter; return pPrt;
} elseif (!mpPrinter)
{ auto pOptions = std::make_unique<SfxItemSetFixed<
SID_PRINTTITLE, SID_PRINTZOOM,
SID_NO_RIGHT_SPACES, SID_SAVE_ONLY_USED_SYMBOLS,
SID_AUTO_CLOSE_BRACKETS, SID_SMEDITWINDOWZOOM,
SID_INLINE_EDIT_ENABLE, SID_INLINE_EDIT_ENABLE>>(GetPool());
SmModule::get()->GetConfig()->ConfigToItemSet(*pOptions);
mpPrinter = VclPtr<SfxPrinter>::Create(std::move(pOptions));
mpPrinter->SetMapMode(MapMode(SmMapUnit()));
} return mpPrinter;
}
OutputDevice* SmDocShell::GetRefDev()
{ if (SfxObjectCreateMode::EMBEDDED == GetCreateMode())
{
OutputDevice* pOutDev = GetDocumentRefDev(); if (pOutDev) return pOutDev;
}
case SID_FONT:
{ // get device used to retrieve the FontList
OutputDevice *pDev = GetPrinter(); if (!pDev || pDev->GetFontFaceCollectionCount() == 0)
pDev = &SmModule::get()->GetDefaultVirtualDev();
OSL_ENSURE (pDev, "device for font list missing" );
for (sal_uInt16 nWh = aIter.FirstWhich(); 0 != nWh; nWh = aIter.NextWhich())
{ switch (nWh)
{ case SID_TEXTMODE:
rSet.Put(SfxBoolItem(SID_TEXTMODE, GetFormat().IsTextmode())); break;
case SID_DOCTEMPLATE :
rSet.DisableItem(SID_DOCTEMPLATE); break;
case SID_AUTO_REDRAW :
rSet.Put(SfxBoolItem(SID_AUTO_REDRAW, SmModule::get()->GetConfig()->IsAutoRedraw())); break;
case SID_MODIFYSTATUS:
{
sal_Unicode cMod = ' '; if (IsModified())
cMod = '*';
rSet.Put(SfxStringItem(SID_MODIFYSTATUS, OUString(cMod)));
} break;
case SID_TEXT:
rSet.Put(SfxStringItem(SID_TEXT, GetText())); break;
case SID_GRAPHIC_SM: //! very old (pre UNO) and ugly hack to invalidate the SmGraphicWidget. //! If mnModifyCount gets changed then the call below will implicitly notify //! SmGraphicController::StateChanged and there the window gets invalidated. //! Thus all the 'mnModifyCount++' before invalidating this slot.
rSet.Put(SfxInt16Item(SID_GRAPHIC_SM, mnModifyCount)); break;
case SID_UNDO: case SID_REDO:
{
SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); if( pFrm )
pFrm->GetSlotState( nWh, nullptr, &rSet ); else
rSet.DisableItem( nWh );
} break;
case SID_GETUNDOSTRINGS: case SID_GETREDOSTRINGS:
{
SfxUndoManager* pTmpUndoMgr = GetUndoManager(); if( pTmpUndoMgr )
{
OUString(SfxUndoManager::*fnGetComment)( size_t, boolconst ) const;
size_t nCount; if( SID_GETUNDOSTRINGS == nWh )
{
nCount = pTmpUndoMgr->GetUndoActionCount();
fnGetComment = &SfxUndoManager::GetUndoActionComment;
} else
{
nCount = pTmpUndoMgr->GetRedoActionCount();
fnGetComment = &SfxUndoManager::GetRedoActionComment;
} if (nCount)
{
OUStringBuffer aBuf; for (size_t n = 0; n < nCount; ++n)
{
aBuf.append((pTmpUndoMgr->*fnGetComment)( n, SfxUndoManager::TopLevel ));
aBuf.append('\n');
}
//TODO/LATER: it's unclear how this interacts with the SFX code // If outplace editing, then don't resize the OutplaceWindow. But the // ObjectShell has to resize. bool bUnLockFrame; if( GetCreateMode() == SfxObjectCreateMode::EMBEDDED && !IsInPlaceActive() && GetFrame() )
{
GetFrame()->LockAdjustPosSizePixel();
bUnLockFrame = true;
} else
bUnLockFrame = false;
// output text on bottom if (bIsPrintFormulaText)
{
vcl::Font aFont(FAMILY_DONTKNOW, Size(0, 600));
aFont.SetAlignment(ALIGN_TOP);
aFont.SetColor(COL_BLACK);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.