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 <sal/config.h>
22 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
23 #include <com/sun/star/uno/Any.h>
25 #include <comphelper/fileformat.h>
26 #include <comphelper/accessibletexthelper.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <rtl/ustring.hxx>
29 #include <sal/log.hxx>
30 #include <unotools/eventcfg.hxx>
31 #include <sfx2/event.hxx>
32 #include <sfx2/app.hxx>
33 #include <sfx2/bindings.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <sfx2/docfilt.hxx>
36 #include <sfx2/msg.hxx>
37 #include <sfx2/objface.hxx>
38 #include <sfx2/printer.hxx>
39 #include <sfx2/request.hxx>
40 #include <sfx2/viewfrm.hxx>
41 #include <comphelper/classids.hxx>
42 #include <sot/formats.hxx>
43 #include <sot/storage.hxx>
44 #include <svl/eitem.hxx>
45 #include <svl/intitem.hxx>
46 #include <svl/itempool.hxx>
47 #include <svl/slstitm.hxx>
48 #include <svl/hint.hxx>
49 #include <svl/stritem.hxx>
50 #include <svl/undo.hxx>
51 #include <svl/whiter.hxx>
52 #include <vcl/mapmod.hxx>
53 #include <vcl/virdev.hxx>
54 #include <tools/mapunit.hxx>
55 #include <vcl/settings.hxx>
57 #include <document.hxx>
62 #include <starmath.hrc>
63 #include <strings.hrc>
66 #include <unomodel.hxx>
67 #include <utility.hxx>
69 #include "mathtype.hxx"
70 #include "ooxmlexport.hxx"
71 #include "ooxmlimport.hxx"
72 #include "rtfexport.hxx"
73 #include <mathmlimport.hxx>
74 #include <mathmlexport.hxx>
75 #include <svx/svxids.hrc>
77 #include <comphelper/diagnose_ex.hxx>
78 #include <visitors.hxx>
79 #include "accessibility.hxx"
80 #include <cfgitem.hxx>
82 #include <oox/mathml/imexport.hxx>
83 #include <ElementsDockingWindow.hxx>
84 #include <smediteng.hxx>
86 using namespace ::com::sun::star
;
87 using namespace ::com::sun::star::accessibility
;
88 using namespace ::com::sun::star::uno
;
90 #define ShellClass_SmDocShell
91 #include <smslots.hxx>
94 SFX_IMPL_SUPERCLASS_INTERFACE(SmDocShell
, SfxObjectShell
)
96 void SmDocShell::InitInterface_Impl()
98 GetStaticInterface()->RegisterPopupMenu("view");
101 void SmDocShell::SetSmSyntaxVersion(sal_uInt16 nSmSyntaxVersion
)
103 mnSmSyntaxVersion
= nSmSyntaxVersion
;
104 maParser
.reset(starmathdatabase::GetVersionSmParser(mnSmSyntaxVersion
));
107 SFX_IMPL_OBJECTFACTORY(SmDocShell
, SvGlobalName(SO3_SM_CLASSID
), "smath" )
109 void SmDocShell::Notify(SfxBroadcaster
&, const SfxHint
& rHint
)
111 if (rHint
.GetId() == SfxHintId::MathFormatChanged
)
113 SetFormulaArranged(false);
115 mnModifyCount
++; //! see comment for SID_GRAPHIC_SM in SmDocShell::GetState
121 void SmDocShell::LoadSymbols()
123 SmModule
*pp
= SM_MOD();
124 pp
->GetSymbolManager().Load();
128 OUString
SmDocShell::GetComment() const
130 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
131 GetModel(), uno::UNO_QUERY_THROW
);
132 uno::Reference
<document::XDocumentProperties
> xDocProps(
133 xDPS
->getDocumentProperties());
134 return xDocProps
->getDescription();
138 void SmDocShell::SetText(const OUString
& rBuffer
)
140 if (rBuffer
== maText
)
143 bool bIsEnabled
= IsEnableSetModified();
145 EnableSetModified( false );
148 SetFormulaArranged( false );
152 SmViewShell
*pViewSh
= SmGetActiveView();
155 pViewSh
->GetViewFrame().GetBindings().Invalidate(SID_TEXT
);
156 if ( SfxObjectCreateMode::EMBEDDED
== GetCreateMode() )
158 // have SwOleClient::FormatChanged() to align the modified formula properly
159 // even if the visible area does not change (e.g. when formula text changes from
160 // "{a over b + c} over d" to "d over {a over b + c}"
161 SfxGetpApp()->NotifyEvent(SfxEventHint( SfxEventHintId::VisAreaChanged
, GlobalEventConfig::GetEventName(GlobalEventId::VISAREACHANGED
), this));
166 pViewSh
->GetGraphicWidget().Invalidate();
170 EnableSetModified( bIsEnabled
);
173 // launch accessible event if necessary
174 SmGraphicAccessible
*pAcc
= pViewSh
? pViewSh
->GetGraphicWidget().GetAccessible_Impl() : nullptr;
177 Any aOldValue
, aNewValue
;
178 if ( comphelper::OCommonAccessibleText::implInitTextChangedEvent( maText
, rBuffer
, aOldValue
, aNewValue
) )
180 pAcc
->LaunchEvent( AccessibleEventId::TEXT_CHANGED
,
181 aOldValue
, aNewValue
);
185 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
186 OnDocumentPrinterChanged(nullptr);
189 void SmDocShell::SetFormat(SmFormat
const & rFormat
)
192 SetFormulaArranged( false );
195 mnModifyCount
++; //! see comment for SID_GRAPHIC_SM in SmDocShell::GetState
197 // don't use SmGetActiveView since the view shell might not be active (0 pointer)
198 // if for example the Basic Macro dialog currently has the focus. Thus:
199 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
202 pFrm
->GetBindings().Invalidate(SID_GRAPHIC_SM
);
203 pFrm
= SfxViewFrame::GetNext( *pFrm
, this );
207 OUString
const & SmDocShell::GetAccessibleText()
210 if (maAccText
.isEmpty())
212 OSL_ENSURE( mpTree
, "Tree missing" );
216 mpTree
->GetAccessibleText(aBuf
);
217 maAccText
= aBuf
.makeStringAndClear();
223 void SmDocShell::Parse()
227 mpTree
= maParser
->Parse(maText
);
228 mnModifyCount
++; //! see comment for SID_GRAPHIC_SM in SmDocShell::GetState
229 SetFormulaArranged( false );
231 maUsedSymbols
= maParser
->GetUsedSymbols();
235 void SmDocShell::ArrangeFormula()
237 if (mbFormulaArranged
)
240 // Only for the duration of the existence of this object the correct settings
241 // at the printer are guaranteed!
242 SmPrinterAccess
aPrtAcc(*this);
243 OutputDevice
* pOutDev
= aPrtAcc
.GetRefDev();
245 SAL_WARN_IF( !pOutDev
, "starmath", "!! SmDocShell::ArrangeFormula: reference device missing !!");
247 // if necessary get another OutputDevice for which we format
250 if (SmViewShell
*pView
= SmGetActiveView())
251 pOutDev
= &pView
->GetGraphicWidget().GetDrawingArea()->get_ref_device();
254 pOutDev
= &SM_MOD()->GetDefaultVirtualDev();
255 pOutDev
->SetMapMode( MapMode(SmMapUnit()) );
258 OSL_ENSURE(pOutDev
->GetMapMode().GetMapUnit() == SmMapUnit(),
259 "Sm : wrong MapMode");
261 const SmFormat
&rFormat
= GetFormat();
262 mpTree
->Prepare(rFormat
, *this, 0);
264 // format/draw formulas always from left to right,
265 // and numbers should not be converted
266 vcl::text::ComplexTextLayoutFlags nLayoutMode
= pOutDev
->GetLayoutMode();
267 pOutDev
->SetLayoutMode( vcl::text::ComplexTextLayoutFlags::Default
);
268 LanguageType nDigitLang
= pOutDev
->GetDigitLanguage();
269 pOutDev
->SetDigitLanguage( LANGUAGE_ENGLISH
);
271 mpTree
->Arrange(*pOutDev
, rFormat
);
273 pOutDev
->SetLayoutMode( nLayoutMode
);
274 pOutDev
->SetDigitLanguage( nDigitLang
);
276 SetFormulaArranged(true);
278 // invalidate accessible text
282 void SmDocShell::UpdateEditEngineDefaultFonts()
284 SmEditEngine::setSmItemPool(mpEditEngineItemPool
.get(), maLinguOptions
);
287 EditEngine
& SmDocShell::GetEditEngine()
292 //! see also SmEditWindow::DataChanged !
294 mpEditEngineItemPool
= EditEngine::CreatePool();
295 SmEditEngine::setSmItemPool(mpEditEngineItemPool
.get(), maLinguOptions
);
296 mpEditEngine
.reset( new SmEditEngine( mpEditEngineItemPool
.get() ) );
297 mpEditEngine
->EraseVirtualDevice();
299 // set initial text if the document already has some...
300 // (may be the case when reloading a doc)
301 OUString
aTxt( GetText() );
303 mpEditEngine
->SetText( aTxt
);
304 mpEditEngine
->ClearModifyFlag();
306 return *mpEditEngine
;
310 void SmDocShell::DrawFormula(OutputDevice
&rDev
, Point
&rPosition
, bool bDrawSelection
)
314 OSL_ENSURE(mpTree
, "Sm : NULL pointer");
318 // Problem: What happens to WYSIWYG? While we're active inplace, we don't have a reference
319 // device and aren't aligned to that either. So now there can be a difference between the
320 // VisArea (i.e. the size within the client) and the current size.
321 // Idea: The difference could be adapted with SmNod::SetSize (no long-term solution)
323 rPosition
.AdjustX(maFormat
.GetDistance( DIS_LEFTSPACE
) );
324 rPosition
.AdjustY(maFormat
.GetDistance( DIS_TOPSPACE
) );
326 //! in case of high contrast-mode (accessibility option!)
327 //! the draw mode needs to be set to default, because when embedding
328 //! Math for example in Calc in "a over b" the fraction bar may not
329 //! be visible else. More generally: the FillColor may have been changed.
330 DrawModeFlags nOldDrawMode
= DrawModeFlags::Default
;
331 bool bRestoreDrawMode
= false;
332 if (OUTDEV_WINDOW
== rDev
.GetOutDevType() &&
333 rDev
.GetOwnerWindow()->GetSettings().GetStyleSettings().GetHighContrastMode())
335 nOldDrawMode
= rDev
.GetDrawMode();
336 rDev
.SetDrawMode( DrawModeFlags::Default
);
337 bRestoreDrawMode
= true;
340 // format/draw formulas always from left to right
341 // and numbers should not be converted
342 vcl::text::ComplexTextLayoutFlags nLayoutMode
= rDev
.GetLayoutMode();
343 rDev
.SetLayoutMode( vcl::text::ComplexTextLayoutFlags::Default
);
344 LanguageType nDigitLang
= rDev
.GetDigitLanguage();
345 rDev
.SetDigitLanguage( LANGUAGE_ENGLISH
);
347 //Set selection if any
348 if(mpCursor
&& bDrawSelection
){
349 mpCursor
->AnnotateSelection();
350 SmSelectionDrawingVisitor(rDev
, mpTree
.get(), rPosition
);
353 //Drawing using visitor
354 SmDrawingVisitor(rDev
, rPosition
, mpTree
.get());
357 rDev
.SetLayoutMode( nLayoutMode
);
358 rDev
.SetDigitLanguage( nDigitLang
);
360 if (bRestoreDrawMode
)
361 rDev
.SetDrawMode( nOldDrawMode
);
364 Size
SmDocShell::GetSize()
374 aRet
= mpTree
->GetSize();
377 aRet
.setWidth( 2000 );
379 aRet
.AdjustWidth(maFormat
.GetDistance( DIS_LEFTSPACE
) +
380 maFormat
.GetDistance( DIS_RIGHTSPACE
) );
381 if ( !aRet
.Height() )
382 aRet
.setHeight( 1000 );
384 aRet
.AdjustHeight(maFormat
.GetDistance( DIS_TOPSPACE
) +
385 maFormat
.GetDistance( DIS_BOTTOMSPACE
) );
391 void SmDocShell::InvalidateCursor(){
395 SmCursor
& SmDocShell::GetCursor(){
397 mpCursor
.reset(new SmCursor(mpTree
.get(), this));
401 bool SmDocShell::HasCursor() const { return mpCursor
!= nullptr; }
403 SmPrinterAccess::SmPrinterAccess( SmDocShell
&rDocShell
)
405 pPrinter
= rDocShell
.GetPrt();
408 pPrinter
->Push( vcl::PushFlags::MAPMODE
);
409 if ( SfxObjectCreateMode::EMBEDDED
== rDocShell
.GetCreateMode() )
411 // if it is an embedded object (without its own printer)
412 // we change the MapMode temporarily.
413 //!If it is a document with its own printer the MapMode should
414 //!be set correct (once) elsewhere(!), in order to avoid numerous
415 //!superfluous pushing and popping of the MapMode when using
418 const MapUnit eOld
= pPrinter
->GetMapMode().GetMapUnit();
419 if ( SmMapUnit() != eOld
)
421 MapMode
aMap( pPrinter
->GetMapMode() );
422 aMap
.SetMapUnit( SmMapUnit() );
423 Point
aTmp( aMap
.GetOrigin() );
424 aTmp
.setX( OutputDevice::LogicToLogic( aTmp
.X(), eOld
, SmMapUnit() ) );
425 aTmp
.setY( OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, SmMapUnit() ) );
426 aMap
.SetOrigin( aTmp
);
427 pPrinter
->SetMapMode( aMap
);
431 pRefDev
= rDocShell
.GetRefDev();
432 if ( !pRefDev
|| pPrinter
.get() == pRefDev
.get() )
435 pRefDev
->Push( vcl::PushFlags::MAPMODE
);
436 if ( SfxObjectCreateMode::EMBEDDED
!= rDocShell
.GetCreateMode() )
439 // if it is an embedded object (without its own printer)
440 // we change the MapMode temporarily.
441 //!If it is a document with its own printer the MapMode should
442 //!be set correct (once) elsewhere(!), in order to avoid numerous
443 //!superfluous pushing and popping of the MapMode when using
446 const MapUnit eOld
= pRefDev
->GetMapMode().GetMapUnit();
447 if ( SmMapUnit() != eOld
)
449 MapMode
aMap( pRefDev
->GetMapMode() );
450 aMap
.SetMapUnit( SmMapUnit() );
451 Point
aTmp( aMap
.GetOrigin() );
452 aTmp
.setX( OutputDevice::LogicToLogic( aTmp
.X(), eOld
, SmMapUnit() ) );
453 aTmp
.setY( OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, SmMapUnit() ) );
454 aMap
.SetOrigin( aTmp
);
455 pRefDev
->SetMapMode( aMap
);
459 SmPrinterAccess::~SmPrinterAccess()
463 if ( pRefDev
&& pRefDev
!= pPrinter
)
467 Printer
* SmDocShell::GetPrt()
469 if (SfxObjectCreateMode::EMBEDDED
== GetCreateMode())
471 // Normally the server provides the printer. But if it doesn't provide one (e.g. because
472 // there is no connection) it still can be the case that we know the printer because it
473 // has been passed on by the server in OnDocumentPrinterChanged and being kept temporarily.
474 Printer
* pPrt
= GetDocumentPrinter();
475 if (!pPrt
&& mpTmpPrinter
)
481 auto pOptions
= std::make_unique
<SfxItemSetFixed
<
482 SID_PRINTTITLE
, SID_PRINTZOOM
,
483 SID_NO_RIGHT_SPACES
, SID_SAVE_ONLY_USED_SYMBOLS
,
484 SID_AUTO_CLOSE_BRACKETS
, SID_SMEDITWINDOWZOOM
>>(GetPool());
485 SmModule
*pp
= SM_MOD();
486 pp
->GetConfig()->ConfigToItemSet(*pOptions
);
487 mpPrinter
= VclPtr
<SfxPrinter
>::Create(std::move(pOptions
));
488 mpPrinter
->SetMapMode(MapMode(SmMapUnit()));
493 OutputDevice
* SmDocShell::GetRefDev()
495 if (SfxObjectCreateMode::EMBEDDED
== GetCreateMode())
497 OutputDevice
* pOutDev
= GetDocumentRefDev();
505 void SmDocShell::SetPrinter( SfxPrinter
*pNew
)
507 mpPrinter
.disposeAndClear();
508 mpPrinter
= pNew
; //Transfer ownership
509 mpPrinter
->SetMapMode( MapMode(SmMapUnit()) );
510 SetFormulaArranged(false);
514 void SmDocShell::OnDocumentPrinterChanged( Printer
*pPrt
)
517 SetFormulaArranged(false);
518 Size aOldSize
= GetVisArea().GetSize();
520 if( aOldSize
!= GetVisArea().GetSize() && !maText
.isEmpty() )
522 mpTmpPrinter
= nullptr;
525 void SmDocShell::Repaint()
527 bool bIsEnabled
= IsEnableSetModified();
529 EnableSetModified( false );
531 SetFormulaArranged(false);
533 Size aVisSize
= GetSize();
534 SetVisAreaSize(aVisSize
);
535 if (SmViewShell
* pViewSh
= SmGetActiveView())
536 pViewSh
->GetGraphicWidget().Invalidate();
539 EnableSetModified(bIsEnabled
);
542 SmDocShell::SmDocShell( SfxModelFlags i_nSfxCreationFlags
)
543 : SfxObjectShell(i_nSfxCreationFlags
)
544 , m_pMlElementTree(nullptr)
546 , mpTmpPrinter(nullptr)
548 , mbFormulaArranged(false)
549 , mnSmSyntaxVersion(SM_MOD()->GetConfig()->GetDefaultSmSyntaxVersion())
551 SvtLinguConfig().GetOptions(maLinguOptions
);
553 SetPool(&SfxGetpApp()->GetPool());
555 SmModule
*pp
= SM_MOD();
556 maFormat
= pp
->GetConfig()->GetStandardFormat();
558 StartListening(maFormat
);
559 StartListening(*pp
->GetConfig());
561 SetBaseModel(new SmModel(this));
562 SetSmSyntaxVersion(mnSmSyntaxVersion
);
564 SetMapUnit(SmMapUnit());
567 SmDocShell::~SmDocShell()
569 SmModule
*pp
= SM_MOD();
571 EndListening(maFormat
);
572 EndListening(*pp
->GetConfig());
575 mpEditEngine
.reset();
576 mpEditEngineItemPool
.clear();
577 mpPrinter
.disposeAndClear();
579 mathml::SmMlIteratorFree(m_pMlElementTree
);
582 bool SmDocShell::ConvertFrom(SfxMedium
&rMedium
)
584 bool bSuccess
= false;
585 const OUString
& rFltName
= rMedium
.GetFilter()->GetFilterName();
587 OSL_ENSURE( rFltName
!= STAROFFICE_XML
, "Wrong filter!");
589 if ( rFltName
== MATHML_XML
)
596 rtl::Reference
<SmModel
> xModel(dynamic_cast<SmModel
*>(GetModel().get()));
597 SmXMLImportWrapper
aEquation(xModel
);
598 aEquation
.useHTMLMLEntities(true);
599 bSuccess
= ( ERRCODE_NONE
== aEquation
.Import(rMedium
) );
603 SvStream
*pStream
= rMedium
.GetInStream();
606 if ( SotStorage::IsStorageFile( pStream
) )
608 tools::SvRef
<SotStorage
> aStorage
= new SotStorage( pStream
, false );
609 if ( aStorage
->IsStream("Equation Native") )
611 // is this a MathType Storage?
612 OUStringBuffer aBuffer
;
613 MathType
aEquation(aBuffer
);
614 bSuccess
= aEquation
.Parse( aStorage
.get() );
617 maText
= aBuffer
.makeStringAndClear();
625 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
627 SetFormulaArranged( false );
636 bool SmDocShell::InitNew( const uno::Reference
< embed::XStorage
>& xStorage
)
639 if ( SfxObjectShell::InitNew( xStorage
) )
642 SetVisArea(tools::Rectangle(Point(0, 0), Size(2000, 1000)));
648 bool SmDocShell::Load( SfxMedium
& rMedium
)
651 if( SfxObjectShell::Load( rMedium
))
653 uno::Reference
< embed::XStorage
> xStorage
= GetMedium()->GetStorage();
654 if (xStorage
->hasByName("content.xml") && xStorage
->isStreamElement("content.xml"))
656 // is this a fabulous math package ?
657 rtl::Reference
<SmModel
> xModel(dynamic_cast<SmModel
*>(GetModel().get()));
658 SmXMLImportWrapper
aEquation(xModel
);
659 auto nError
= aEquation
.Import(rMedium
);
660 bRet
= ERRCODE_NONE
== nError
;
665 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
667 SetFormulaArranged( false );
676 bool SmDocShell::Save()
678 //! apply latest changes if necessary
681 if ( SfxObjectShell::Save() )
688 Reference
<css::frame::XModel
> xModel(GetModel());
689 SmXMLExportWrapper
aEquation(xModel
);
690 aEquation
.SetFlat(false);
691 return aEquation
.Export(*GetMedium());
698 * replace bad characters that can not be saved. (#i74144)
700 void SmDocShell::ReplaceBadChars()
702 bool bReplace
= false;
707 OUStringBuffer
aBuf( mpEditEngine
->GetText() );
709 for (sal_Int32 i
= 0; i
< aBuf
.getLength(); ++i
)
711 if (aBuf
[i
] < ' ' && aBuf
[i
] != '\r' && aBuf
[i
] != '\n' && aBuf
[i
] != '\t')
719 maText
= aBuf
.makeStringAndClear();
723 void SmDocShell::UpdateText()
725 if (mpEditEngine
&& mpEditEngine
->IsModified())
727 OUString
aEngTxt( mpEditEngine
->GetText() );
728 if (GetText() != aEngTxt
)
734 bool SmDocShell::SaveAs( SfxMedium
& rMedium
)
738 //! apply latest changes if necessary
741 if ( SfxObjectShell::SaveAs( rMedium
) )
748 Reference
<css::frame::XModel
> xModel(GetModel());
749 SmXMLExportWrapper
aEquation(xModel
);
750 aEquation
.SetFlat(false);
751 bRet
= aEquation
.Export(rMedium
);
756 bool SmDocShell::ConvertTo( SfxMedium
&rMedium
)
759 std::shared_ptr
<const SfxFilter
> pFlt
= rMedium
.GetFilter();
767 const OUString
& rFltName
= pFlt
->GetFilterName();
768 if(rFltName
== STAROFFICE_XML
)
770 Reference
<css::frame::XModel
> xModel(GetModel());
771 SmXMLExportWrapper
aEquation(xModel
);
772 aEquation
.SetFlat(false);
773 bRet
= aEquation
.Export(rMedium
);
775 else if(rFltName
== MATHML_XML
)
777 Reference
<css::frame::XModel
> xModel(GetModel());
778 SmXMLExportWrapper
aEquation(xModel
);
779 aEquation
.SetFlat(true);
780 aEquation
.SetUseHTMLMLEntities(true);
781 bRet
= aEquation
.Export(rMedium
);
783 else if (pFlt
->GetFilterName() == "MathType 3.x")
784 bRet
= WriteAsMathType3( rMedium
);
789 void SmDocShell::writeFormulaOoxml(
790 ::sax_fastparser::FSHelperPtr
const& pSerializer
,
791 oox::core::OoxmlVersion
const version
,
792 oox::drawingml::DocumentType
const documentType
,
793 const sal_Int8 nAlign
)
799 SmOoxmlExport
aEquation(mpTree
.get(), version
, documentType
);
800 if(documentType
== oox::drawingml::DOCUMENT_DOCX
)
801 aEquation
.ConvertFromStarMath( pSerializer
, nAlign
);
803 aEquation
.ConvertFromStarMath(pSerializer
, oox::FormulaImExportBase::eFormulaAlign::INLINE
);
806 void SmDocShell::writeFormulaRtf(OStringBuffer
& rBuffer
, rtl_TextEncoding nEncoding
)
812 SmRtfExport
aEquation(mpTree
.get());
813 aEquation
.ConvertFromStarMath(rBuffer
, nEncoding
);
816 void SmDocShell::readFormulaOoxml( oox::formulaimport::XmlStream
& stream
)
818 SmOoxmlImport
aEquation( stream
);
819 SetText( aEquation
.ConvertToStarMath());
822 void SmDocShell::Execute(SfxRequest
& rReq
)
824 switch (rReq
.GetSlot())
828 SmFormat aOldFormat
= GetFormat();
829 SmFormat
aNewFormat( aOldFormat
);
830 aNewFormat
.SetTextmode(!aOldFormat
.IsTextmode());
832 SfxUndoManager
*pTmpUndoMgr
= GetUndoManager();
834 pTmpUndoMgr
->AddUndoAction(
835 std::make_unique
<SmFormatAction
>(this, aOldFormat
, aNewFormat
));
837 SetFormat( aNewFormat
);
842 case SID_AUTO_REDRAW
:
844 SmModule
*pp
= SM_MOD();
845 bool bRedraw
= pp
->GetConfig()->IsAutoRedraw();
846 pp
->GetConfig()->SetAutoRedraw(!bRedraw
);
850 case SID_LOADSYMBOLS
:
854 case SID_SAVESYMBOLS
:
860 // get device used to retrieve the FontList
861 OutputDevice
*pDev
= GetPrinter();
862 if (!pDev
|| pDev
->GetFontFaceCollectionCount() == 0)
863 pDev
= &SM_MOD()->GetDefaultVirtualDev();
864 OSL_ENSURE (pDev
, "device for font list missing" );
866 SmFontTypeDialog
aFontTypeDialog(rReq
.GetFrameWeld(), pDev
);
868 SmFormat aOldFormat
= GetFormat();
869 aFontTypeDialog
.ReadFrom( aOldFormat
);
870 if (aFontTypeDialog
.run() == RET_OK
)
872 SmFormat
aNewFormat( aOldFormat
);
874 aFontTypeDialog
.WriteTo(aNewFormat
);
875 SfxUndoManager
*pTmpUndoMgr
= GetUndoManager();
877 pTmpUndoMgr
->AddUndoAction(
878 std::make_unique
<SmFormatAction
>(this, aOldFormat
, aNewFormat
));
880 SetFormat( aNewFormat
);
888 SmFontSizeDialog
aFontSizeDialog(rReq
.GetFrameWeld());
890 SmFormat aOldFormat
= GetFormat();
891 aFontSizeDialog
.ReadFrom( aOldFormat
);
892 if (aFontSizeDialog
.run() == RET_OK
)
894 SmFormat
aNewFormat( aOldFormat
);
896 aFontSizeDialog
.WriteTo(aNewFormat
);
898 SfxUndoManager
*pTmpUndoMgr
= GetUndoManager();
900 pTmpUndoMgr
->AddUndoAction(
901 std::make_unique
<SmFormatAction
>(this, aOldFormat
, aNewFormat
));
903 SetFormat( aNewFormat
);
911 SmDistanceDialog
aDistanceDialog(rReq
.GetFrameWeld());
913 SmFormat aOldFormat
= GetFormat();
914 aDistanceDialog
.ReadFrom( aOldFormat
);
915 if (aDistanceDialog
.run() == RET_OK
)
917 SmFormat
aNewFormat( aOldFormat
);
919 aDistanceDialog
.WriteTo(aNewFormat
);
921 SfxUndoManager
*pTmpUndoMgr
= GetUndoManager();
923 pTmpUndoMgr
->AddUndoAction(
924 std::make_unique
<SmFormatAction
>(this, aOldFormat
, aNewFormat
));
926 SetFormat( aNewFormat
);
934 SmAlignDialog
aAlignDialog(rReq
.GetFrameWeld());
936 SmFormat aOldFormat
= GetFormat();
937 aAlignDialog
.ReadFrom( aOldFormat
);
938 if (aAlignDialog
.run() == RET_OK
)
940 SmFormat
aNewFormat( aOldFormat
);
942 aAlignDialog
.WriteTo(aNewFormat
);
944 SmModule
*pp
= SM_MOD();
945 SmFormat
aFmt( pp
->GetConfig()->GetStandardFormat() );
946 aAlignDialog
.WriteTo( aFmt
);
947 pp
->GetConfig()->SetStandardFormat( aFmt
);
949 SfxUndoManager
*pTmpUndoMgr
= GetUndoManager();
951 pTmpUndoMgr
->AddUndoAction(
952 std::make_unique
<SmFormatAction
>(this, aOldFormat
, aNewFormat
));
954 SetFormat( aNewFormat
);
962 const SfxStringItem
& rItem
= rReq
.GetArgs()->Get(SID_TEXT
);
963 if (GetText() != rItem
.GetValue())
964 SetText(rItem
.GetValue());
971 SfxUndoManager
* pTmpUndoMgr
= GetUndoManager();
974 sal_uInt16 nId
= rReq
.GetSlot(), nCnt
= 1;
975 const SfxItemSet
* pArgs
= rReq
.GetArgs();
976 const SfxPoolItem
* pItem
;
977 if( pArgs
&& SfxItemState::SET
== pArgs
->GetItemState( nId
, false, &pItem
))
978 nCnt
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
980 bool (SfxUndoManager::*fnDo
)();
983 if( SID_UNDO
== rReq
.GetSlot() )
985 nCount
= pTmpUndoMgr
->GetUndoActionCount();
986 fnDo
= &SfxUndoManager::Undo
;
990 nCount
= pTmpUndoMgr
->GetRedoActionCount();
991 fnDo
= &SfxUndoManager::Redo
;
996 for( ; nCnt
&& nCount
; --nCnt
, --nCount
)
997 (pTmpUndoMgr
->*fnDo
)();
999 catch( const Exception
& )
1001 DBG_UNHANDLED_EXCEPTION("starmath");
1006 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1009 SfxBindings
& rBind
= pFrm
->GetBindings();
1010 rBind
.Invalidate(SID_UNDO
);
1011 rBind
.Invalidate(SID_REDO
);
1012 rBind
.Invalidate(SID_REPEAT
);
1013 rBind
.Invalidate(SID_CLEARHISTORY
);
1014 pFrm
= SfxViewFrame::GetNext( *pFrm
, this );
1024 void SmDocShell::GetState(SfxItemSet
&rSet
)
1026 SfxWhichIter
aIter(rSet
);
1028 for (sal_uInt16 nWh
= aIter
.FirstWhich(); 0 != nWh
; nWh
= aIter
.NextWhich())
1033 rSet
.Put(SfxBoolItem(SID_TEXTMODE
, GetFormat().IsTextmode()));
1036 case SID_DOCTEMPLATE
:
1037 rSet
.DisableItem(SID_DOCTEMPLATE
);
1040 case SID_AUTO_REDRAW
:
1042 SmModule
*pp
= SM_MOD();
1043 bool bRedraw
= pp
->GetConfig()->IsAutoRedraw();
1045 rSet
.Put(SfxBoolItem(SID_AUTO_REDRAW
, bRedraw
));
1049 case SID_MODIFYSTATUS
:
1051 sal_Unicode cMod
= ' ';
1054 rSet
.Put(SfxStringItem(SID_MODIFYSTATUS
, OUString(cMod
)));
1059 rSet
.Put(SfxStringItem(SID_TEXT
, GetText()));
1062 case SID_GRAPHIC_SM
:
1063 //! very old (pre UNO) and ugly hack to invalidate the SmGraphicWidget.
1064 //! If mnModifyCount gets changed then the call below will implicitly notify
1065 //! SmGraphicController::StateChanged and there the window gets invalidated.
1066 //! Thus all the 'mnModifyCount++' before invalidating this slot.
1067 rSet
.Put(SfxInt16Item(SID_GRAPHIC_SM
, mnModifyCount
));
1073 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1075 pFrm
->GetSlotState( nWh
, nullptr, &rSet
);
1077 rSet
.DisableItem( nWh
);
1081 case SID_GETUNDOSTRINGS
:
1082 case SID_GETREDOSTRINGS
:
1084 SfxUndoManager
* pTmpUndoMgr
= GetUndoManager();
1087 OUString(SfxUndoManager::*fnGetComment
)( size_t, bool const ) const;
1090 if( SID_GETUNDOSTRINGS
== nWh
)
1092 nCount
= pTmpUndoMgr
->GetUndoActionCount();
1093 fnGetComment
= &SfxUndoManager::GetUndoActionComment
;
1097 nCount
= pTmpUndoMgr
->GetRedoActionCount();
1098 fnGetComment
= &SfxUndoManager::GetRedoActionComment
;
1102 OUStringBuffer aBuf
;
1103 for (size_t n
= 0; n
< nCount
; ++n
)
1105 aBuf
.append((pTmpUndoMgr
->*fnGetComment
)( n
, SfxUndoManager::TopLevel
));
1109 SfxStringListItem
aItem( nWh
);
1110 aItem
.SetString( aBuf
.makeStringAndClear() );
1115 rSet
.DisableItem( nWh
);
1123 SfxUndoManager
*SmDocShell::GetUndoManager()
1127 return &mpEditEngine
->GetUndoManager();
1131 void SmDocShell::SaveSymbols()
1133 SmModule
*pp
= SM_MOD();
1134 pp
->GetSymbolManager().Save();
1138 void SmDocShell::Draw(OutputDevice
*pDevice
,
1140 sal_uInt16
/*nAspect*/,
1141 bool /*bOutputForScreen*/)
1143 pDevice
->IntersectClipRegion(GetVisArea());
1145 DrawFormula(*pDevice
, atmppoint
);
1148 SfxItemPool
& SmDocShell::GetPool()
1150 return SfxGetpApp()->GetPool();
1153 void SmDocShell::SetVisArea(const tools::Rectangle
& rVisArea
)
1155 tools::Rectangle
aNewRect(rVisArea
);
1157 aNewRect
.SetPos(Point());
1159 if (aNewRect
.IsWidthEmpty())
1160 aNewRect
.SetRight( 2000 );
1161 if (aNewRect
.IsHeightEmpty())
1162 aNewRect
.SetBottom( 1000 );
1164 bool bIsEnabled
= IsEnableSetModified();
1166 EnableSetModified( false );
1168 //TODO/LATER: it's unclear how this interacts with the SFX code
1169 // If outplace editing, then don't resize the OutplaceWindow. But the
1170 // ObjectShell has to resize.
1172 if( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
&& !IsInPlaceActive() && GetFrame() )
1174 GetFrame()->LockAdjustPosSizePixel();
1175 bUnLockFrame
= true;
1178 bUnLockFrame
= false;
1180 SfxObjectShell::SetVisArea( aNewRect
);
1183 GetFrame()->UnlockAdjustPosSizePixel();
1186 EnableSetModified( bIsEnabled
);
1190 void SmDocShell::FillClass(SvGlobalName
* pClassName
,
1191 SotClipboardFormatId
* pFormat
,
1192 OUString
* pFullTypeName
,
1193 sal_Int32 nFileFormat
,
1194 bool bTemplate
/* = false */) const
1196 if (nFileFormat
== SOFFICE_FILEFORMAT_60
)
1198 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1199 *pFormat
= SotClipboardFormatId::STARMATH_60
;
1200 *pFullTypeName
= SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
);
1202 else if (nFileFormat
== SOFFICE_FILEFORMAT_8
)
1204 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1205 *pFormat
= bTemplate
? SotClipboardFormatId::STARMATH_8_TEMPLATE
: SotClipboardFormatId::STARMATH_8
;
1206 *pFullTypeName
= SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
);
1210 void SmDocShell::SetModified(bool bModified
)
1212 if( IsEnableSetModified() )
1214 SfxObjectShell::SetModified( bModified
);
1215 Broadcast(SfxHint(SfxHintId::DocChanged
));
1219 bool SmDocShell::WriteAsMathType3( SfxMedium
& rMedium
)
1221 OUStringBuffer
aTextAsBuffer(maText
);
1222 MathType
aEquation(aTextAsBuffer
, mpTree
.get());
1223 return aEquation
.ConvertFromStarMath( rMedium
);
1226 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */