1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
21 #include <com/sun/star/uno/Any.h>
23 #include <comphelper/fileformat.h>
24 #include <comphelper/accessibletexthelper.hxx>
25 #include <o3tl/make_unique.hxx>
26 #include <rtl/ustrbuf.hxx>
27 #include <rtl/ustring.hxx>
28 #include <unotools/eventcfg.hxx>
29 #include <sfx2/event.hxx>
30 #include <sfx2/app.hxx>
31 #include <sfx2/docfile.hxx>
32 #include <sfx2/docfilt.hxx>
33 #include <sfx2/msg.hxx>
34 #include <sfx2/objface.hxx>
35 #include <sfx2/printer.hxx>
36 #include <sfx2/request.hxx>
37 #include <sfx2/viewfrm.hxx>
38 #include <comphelper/classids.hxx>
39 #include <sot/formats.hxx>
40 #include <sot/storage.hxx>
41 #include <svl/eitem.hxx>
42 #include <svl/intitem.hxx>
43 #include <svl/itempool.hxx>
44 #include <svl/slstitm.hxx>
45 #include <svl/hint.hxx>
46 #include <svl/stritem.hxx>
47 #include <svl/undo.hxx>
48 #include <svl/whiter.hxx>
49 #include <editeng/editeng.hxx>
50 #include <editeng/editstat.hxx>
51 #include <editeng/eeitem.hxx>
52 #include <editeng/fhgtitem.hxx>
53 #include <editeng/fontitem.hxx>
54 #include <vcl/mapmod.hxx>
55 #include <tools/mapunit.hxx>
56 #include <vcl/settings.hxx>
58 #include <document.hxx>
62 #include <starmath.hrc>
63 #include <strings.hrc>
65 #include <unomodel.hxx>
66 #include <utility.hxx>
68 #include "mathtype.hxx"
69 #include "ooxmlexport.hxx"
70 #include "ooxmlimport.hxx"
71 #include "rtfexport.hxx"
72 #include "mathmlimport.hxx"
73 #include "mathmlexport.hxx"
74 #include <svx/svxids.hrc>
76 #include <tools/diagnose_ex.h>
77 #include <visitors.hxx>
78 #include "accessibility.hxx"
79 #include "cfgitem.hxx"
83 using namespace ::com::sun::star
;
84 using namespace ::com::sun::star::accessibility
;
85 using namespace ::com::sun::star::uno
;
87 #define ShellClass_SmDocShell
88 #include <smslots.hxx>
91 SFX_IMPL_SUPERCLASS_INTERFACE(SmDocShell
, SfxObjectShell
)
93 void SmDocShell::InitInterface_Impl()
95 GetStaticInterface()->RegisterPopupMenu("view");
98 SFX_IMPL_OBJECTFACTORY(SmDocShell
, SvGlobalName(SO3_SM_CLASSID
), SfxObjectShellFlags::STD_NORMAL
, "smath" )
100 void SmDocShell::Notify(SfxBroadcaster
&, const SfxHint
& rHint
)
102 if (rHint
.GetId() == SfxHintId::MathFormatChanged
)
104 SetFormulaArranged(false);
106 mnModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
112 void SmDocShell::LoadSymbols()
114 SmModule
*pp
= SM_MOD();
115 pp
->GetSymbolManager().Load();
119 const OUString
SmDocShell::GetComment() const
121 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
122 GetModel(), uno::UNO_QUERY_THROW
);
123 uno::Reference
<document::XDocumentProperties
> xDocProps(
124 xDPS
->getDocumentProperties());
125 return xDocProps
->getDescription();
129 void SmDocShell::SetText(const OUString
& rBuffer
)
131 if (rBuffer
!= maText
)
133 bool bIsEnabled
= IsEnableSetModified();
135 EnableSetModified( false );
138 SetFormulaArranged( false );
142 SmViewShell
*pViewSh
= SmGetActiveView();
145 pViewSh
->GetViewFrame()->GetBindings().Invalidate(SID_TEXT
);
146 if ( SfxObjectCreateMode::EMBEDDED
== GetCreateMode() )
148 // have SwOleClient::FormatChanged() to align the modified formula properly
149 // even if the visible area does not change (e.g. when formula text changes from
150 // "{a over b + c} over d" to "d over {a over b + c}"
151 SfxGetpApp()->NotifyEvent(SfxEventHint( SfxEventHintId::VisAreaChanged
, GlobalEventConfig::GetEventName(GlobalEventId::VISAREACHANGED
), this));
156 pViewSh
->GetGraphicWindow().Invalidate();
160 EnableSetModified( bIsEnabled
);
163 // launch accessible event if necessary
164 SmGraphicAccessible
*pAcc
= pViewSh
? pViewSh
->GetGraphicWindow().GetAccessible_Impl() : nullptr;
167 Any aOldValue
, aNewValue
;
168 if ( comphelper::OCommonAccessibleText::implInitTextChangedEvent( maText
, rBuffer
, aOldValue
, aNewValue
) )
170 pAcc
->LaunchEvent( AccessibleEventId::TEXT_CHANGED
,
171 aOldValue
, aNewValue
);
175 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
176 OnDocumentPrinterChanged(nullptr);
180 void SmDocShell::SetFormat(SmFormat
const & rFormat
)
183 SetFormulaArranged( false );
186 mnModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
188 // don't use SmGetActiveView since the view shell might not be active (0 pointer)
189 // if for example the Basic Macro dialog currently has the focus. Thus:
190 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
193 pFrm
->GetBindings().Invalidate(SID_GAPHIC_SM
);
194 pFrm
= SfxViewFrame::GetNext( *pFrm
, this );
198 OUString
const & SmDocShell::GetAccessibleText()
201 if (maAccText
.isEmpty())
203 OSL_ENSURE( mpTree
, "Tree missing" );
207 mpTree
->GetAccessibleText(aBuf
);
208 maAccText
= aBuf
.makeStringAndClear();
214 void SmDocShell::Parse()
218 mpTree
= maParser
.Parse(maText
);
219 mnModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
220 SetFormulaArranged( false );
222 maUsedSymbols
= maParser
.GetUsedSymbols();
226 void SmDocShell::ArrangeFormula()
228 if (mbFormulaArranged
)
231 // Only for the duration of the existence of this object the correct settings
232 // at the printer are guaranteed!
233 SmPrinterAccess
aPrtAcc(*this);
234 OutputDevice
* pOutDev
= aPrtAcc
.GetRefDev();
236 SAL_WARN_IF( !pOutDev
, "starmath", "!! SmDocShell::ArrangeFormula: reference device missing !!");
238 // if necessary get another OutputDevice for which we format
241 SmViewShell
*pView
= SmGetActiveView();
243 pOutDev
= &pView
->GetGraphicWindow();
246 pOutDev
= &SM_MOD()->GetDefaultVirtualDev();
247 pOutDev
->SetMapMode( MapMode(MapUnit::Map100thMM
) );
250 OSL_ENSURE(pOutDev
->GetMapMode().GetMapUnit() == MapUnit::Map100thMM
,
251 "Sm : wrong MapMode");
253 const SmFormat
&rFormat
= GetFormat();
254 mpTree
->Prepare(rFormat
, *this, 0);
256 // format/draw formulas always from left to right,
257 // and numbers should not be converted
258 ComplexTextLayoutFlags nLayoutMode
= pOutDev
->GetLayoutMode();
259 pOutDev
->SetLayoutMode( ComplexTextLayoutFlags::Default
);
260 LanguageType nDigitLang
= pOutDev
->GetDigitLanguage();
261 pOutDev
->SetDigitLanguage( LANGUAGE_ENGLISH
);
263 mpTree
->Arrange(*pOutDev
, rFormat
);
265 pOutDev
->SetLayoutMode( nLayoutMode
);
266 pOutDev
->SetDigitLanguage( nDigitLang
);
268 SetFormulaArranged(true);
270 // invalidate accessible text
274 void SetEditEngineDefaultFonts(SfxItemPool
&rEditEngineItemPool
, const SvtLinguOptions
&rOpt
)
276 // set fonts to be used
278 LanguageType nFallbackLang
;
280 DefaultFontType nFontType
;
281 sal_uInt16 nFontInfoId
;
284 // info to get western font to be used
285 { LANGUAGE_ENGLISH_US
, LANGUAGE_NONE
,
286 DefaultFontType::FIXED
, EE_CHAR_FONTINFO
},
287 // info to get CJK font to be used
288 { LANGUAGE_JAPANESE
, LANGUAGE_NONE
,
289 DefaultFontType::CJK_TEXT
, EE_CHAR_FONTINFO_CJK
},
290 // info to get CTL font to be used
291 { LANGUAGE_ARABIC_SAUDI_ARABIA
, LANGUAGE_NONE
,
292 DefaultFontType::CTL_TEXT
, EE_CHAR_FONTINFO_CTL
}
294 aTable
[0].nLang
= rOpt
.nDefaultLanguage
;
295 aTable
[1].nLang
= rOpt
.nDefaultLanguage_CJK
;
296 aTable
[2].nLang
= rOpt
.nDefaultLanguage_CTL
;
298 for (FontDta
& rFntDta
: aTable
)
300 LanguageType nLang
= (LANGUAGE_NONE
== rFntDta
.nLang
) ?
301 rFntDta
.nFallbackLang
: rFntDta
.nLang
;
302 vcl::Font aFont
= OutputDevice::GetDefaultFont(
303 rFntDta
.nFontType
, nLang
, GetDefaultFontFlags::OnlyOne
);
304 rEditEngineItemPool
.SetPoolDefaultItem(
305 SvxFontItem( aFont
.GetFamilyType(), aFont
.GetFamilyName(),
306 aFont
.GetStyleName(), aFont
.GetPitch(), aFont
.GetCharSet(),
307 rFntDta
.nFontInfoId
) );
311 SvxFontHeightItem
aFontHeigt(
312 Application::GetDefaultDevice()->LogicToPixel(
313 Size( 0, 11 ), MapMode( MapUnit::MapPoint
) ).Height(), 100,
314 EE_CHAR_FONTHEIGHT
);
315 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
316 aFontHeigt
.SetWhich( EE_CHAR_FONTHEIGHT_CJK
);
317 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
318 aFontHeigt
.SetWhich( EE_CHAR_FONTHEIGHT_CTL
);
319 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
322 EditEngine
& SmDocShell::GetEditEngine()
327 //! see also SmEditWindow::DataChanged !
330 mpEditEngineItemPool
= EditEngine::CreatePool();
332 SetEditEngineDefaultFonts(*mpEditEngineItemPool
, maLinguOptions
);
334 mpEditEngine
.reset( new EditEngine( mpEditEngineItemPool
) );
336 mpEditEngine
->SetAddExtLeading(true);
338 mpEditEngine
->EnableUndo( true );
339 mpEditEngine
->SetDefTab( sal_uInt16(
340 Application::GetDefaultDevice()->GetTextWidth("XXXX")) );
342 mpEditEngine
->SetControlWord(
343 (mpEditEngine
->GetControlWord() | EEControlBits::AUTOINDENTING
) &
344 EEControlBits(~EEControlBits::UNDOATTRIBS
) &
345 EEControlBits(~EEControlBits::PASTESPECIAL
) );
347 mpEditEngine
->SetWordDelimiters(" .=+-*/(){}[];\"");
348 mpEditEngine
->SetRefMapMode(MapMode(MapUnit::MapPixel
));
350 mpEditEngine
->SetPaperSize( Size( 800, 0 ) );
352 mpEditEngine
->EraseVirtualDevice();
354 // set initial text if the document already has some...
355 // (may be the case when reloading a doc)
356 OUString
aTxt( GetText() );
358 mpEditEngine
->SetText( aTxt
);
360 mpEditEngine
->ClearModifyFlag();
363 return *mpEditEngine
;
367 SfxItemPool
& SmDocShell::GetEditEngineItemPool()
369 if (!mpEditEngineItemPool
)
371 assert(mpEditEngineItemPool
&& "EditEngineItemPool missing");
372 return *mpEditEngineItemPool
;
375 void SmDocShell::DrawFormula(OutputDevice
&rDev
, Point
&rPosition
, bool bDrawSelection
)
379 OSL_ENSURE(mpTree
, "Sm : NULL pointer");
383 // Problem: What happens to WYSIWYG? While we're active inplace, we don't have a reference
384 // device and aren't aligned to that either. So now there can be a difference between the
385 // VisArea (i.e. the size within the client) and the current size.
386 // Idea: The difference could be adapted with SmNod::SetSize (no long-term solution)
388 rPosition
.AdjustX(maFormat
.GetDistance( DIS_LEFTSPACE
) );
389 rPosition
.AdjustY(maFormat
.GetDistance( DIS_TOPSPACE
) );
391 //! in case of high contrast-mode (accessibility option!)
392 //! the draw mode needs to be set to default, because when imbedding
393 //! Math for example in Calc in "a over b" the fraction bar may not
394 //! be visible else. More generally: the FillColor may have been changed.
395 DrawModeFlags nOldDrawMode
= DrawModeFlags::Default
;
396 bool bRestoreDrawMode
= false;
397 if (OUTDEV_WINDOW
== rDev
.GetOutDevType() &&
398 static_cast<vcl::Window
&>(rDev
).GetSettings().GetStyleSettings().GetHighContrastMode())
400 nOldDrawMode
= rDev
.GetDrawMode();
401 rDev
.SetDrawMode( DrawModeFlags::Default
);
402 bRestoreDrawMode
= true;
405 // format/draw formulas always from left to right
406 // and numbers should not be converted
407 ComplexTextLayoutFlags nLayoutMode
= rDev
.GetLayoutMode();
408 rDev
.SetLayoutMode( ComplexTextLayoutFlags::Default
);
409 LanguageType nDigitLang
= rDev
.GetDigitLanguage();
410 rDev
.SetDigitLanguage( LANGUAGE_ENGLISH
);
412 //Set selection if any
413 if(mpCursor
&& bDrawSelection
){
414 mpCursor
->AnnotateSelection();
415 SmSelectionDrawingVisitor(rDev
, mpTree
.get(), rPosition
);
418 //Drawing using visitor
419 SmDrawingVisitor(rDev
, rPosition
, mpTree
.get());
422 rDev
.SetLayoutMode( nLayoutMode
);
423 rDev
.SetDigitLanguage( nDigitLang
);
425 if (bRestoreDrawMode
)
426 rDev
.SetDrawMode( nOldDrawMode
);
429 Size
SmDocShell::GetSize()
439 aRet
= mpTree
->GetSize();
442 aRet
.setWidth( 2000 );
444 aRet
.AdjustWidth(maFormat
.GetDistance( DIS_LEFTSPACE
) +
445 maFormat
.GetDistance( DIS_RIGHTSPACE
) );
446 if ( !aRet
.Height() )
447 aRet
.setHeight( 1000 );
449 aRet
.AdjustHeight(maFormat
.GetDistance( DIS_TOPSPACE
) +
450 maFormat
.GetDistance( DIS_BOTTOMSPACE
) );
456 void SmDocShell::InvalidateCursor(){
460 SmCursor
& SmDocShell::GetCursor(){
462 mpCursor
.reset(new SmCursor(mpTree
.get(), this));
466 bool SmDocShell::HasCursor()
468 return mpCursor
.get() != nullptr;
471 SmPrinterAccess::SmPrinterAccess( SmDocShell
&rDocShell
)
473 pPrinter
= rDocShell
.GetPrt();
476 pPrinter
->Push( PushFlags::MAPMODE
);
477 if ( SfxObjectCreateMode::EMBEDDED
== rDocShell
.GetCreateMode() )
479 // if it is an embedded object (without its own printer)
480 // we change the MapMode temporarily.
481 //!If it is a document with its own printer the MapMode should
482 //!be set correct (once) elsewhere(!), in order to avoid numerous
483 //!superfluous pushing and popping of the MapMode when using
486 const MapUnit eOld
= pPrinter
->GetMapMode().GetMapUnit();
487 if ( MapUnit::Map100thMM
!= eOld
)
489 MapMode
aMap( pPrinter
->GetMapMode() );
490 aMap
.SetMapUnit( MapUnit::Map100thMM
);
491 Point
aTmp( aMap
.GetOrigin() );
492 aTmp
.setX( OutputDevice::LogicToLogic( aTmp
.X(), eOld
, MapUnit::Map100thMM
) );
493 aTmp
.setY( OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, MapUnit::Map100thMM
) );
494 aMap
.SetOrigin( aTmp
);
495 pPrinter
->SetMapMode( aMap
);
499 if ( (pRefDev
= rDocShell
.GetRefDev()) && pPrinter
.get() != pRefDev
.get() )
501 pRefDev
->Push( PushFlags::MAPMODE
);
502 if ( SfxObjectCreateMode::EMBEDDED
== rDocShell
.GetCreateMode() )
504 // if it is an embedded object (without its own printer)
505 // we change the MapMode temporarily.
506 //!If it is a document with its own printer the MapMode should
507 //!be set correct (once) elsewhere(!), in order to avoid numerous
508 //!superfluous pushing and popping of the MapMode when using
511 const MapUnit eOld
= pRefDev
->GetMapMode().GetMapUnit();
512 if ( MapUnit::Map100thMM
!= eOld
)
514 MapMode
aMap( pRefDev
->GetMapMode() );
515 aMap
.SetMapUnit( MapUnit::Map100thMM
);
516 Point
aTmp( aMap
.GetOrigin() );
517 aTmp
.setX( OutputDevice::LogicToLogic( aTmp
.X(), eOld
, MapUnit::Map100thMM
) );
518 aTmp
.setY( OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, MapUnit::Map100thMM
) );
519 aMap
.SetOrigin( aTmp
);
520 pRefDev
->SetMapMode( aMap
);
526 SmPrinterAccess::~SmPrinterAccess()
530 if ( pRefDev
&& pRefDev
!= pPrinter
)
534 Printer
* SmDocShell::GetPrt()
536 if (SfxObjectCreateMode::EMBEDDED
== GetCreateMode())
538 // Normally the server provides the printer. But if it doesn't provide one (e.g. because
539 // there is no connection) it still can be the case that we know the printer because it
540 // has been passed on by the server in OnDocumentPrinterChanged and being kept temporarily.
541 Printer
* pPrt
= GetDocumentPrinter();
542 if (!pPrt
&& mpTmpPrinter
)
548 auto pOptions
= o3tl::make_unique
<SfxItemSet
>(
551 SID_PRINTTITLE
, SID_PRINTZOOM
,
552 SID_NO_RIGHT_SPACES
, SID_SAVE_ONLY_USED_SYMBOLS
,
553 SID_AUTO_CLOSE_BRACKETS
, SID_AUTO_CLOSE_BRACKETS
>{});
554 SmModule
*pp
= SM_MOD();
555 pp
->GetConfig()->ConfigToItemSet(*pOptions
);
556 mpPrinter
= VclPtr
<SfxPrinter
>::Create(std::move(pOptions
));
557 mpPrinter
->SetMapMode(MapMode(MapUnit::Map100thMM
));
562 OutputDevice
* SmDocShell::GetRefDev()
564 if (SfxObjectCreateMode::EMBEDDED
== GetCreateMode())
566 OutputDevice
* pOutDev
= GetDocumentRefDev();
574 void SmDocShell::SetPrinter( SfxPrinter
*pNew
)
576 mpPrinter
.disposeAndClear();
577 mpPrinter
= pNew
; //Transfer ownership
578 mpPrinter
->SetMapMode( MapMode(MapUnit::Map100thMM
) );
579 SetFormulaArranged(false);
583 void SmDocShell::OnDocumentPrinterChanged( Printer
*pPrt
)
586 SetFormulaArranged(false);
587 Size aOldSize
= GetVisArea().GetSize();
589 if( aOldSize
!= GetVisArea().GetSize() && !maText
.isEmpty() )
591 mpTmpPrinter
= nullptr;
594 void SmDocShell::Repaint()
596 bool bIsEnabled
= IsEnableSetModified();
598 EnableSetModified( false );
600 SetFormulaArranged(false);
602 Size aVisSize
= GetSize();
603 SetVisAreaSize(aVisSize
);
604 SmViewShell
* pViewSh
= SmGetActiveView();
606 pViewSh
->GetGraphicWindow().Invalidate();
609 EnableSetModified(bIsEnabled
);
612 SmDocShell::SmDocShell( SfxModelFlags i_nSfxCreationFlags
)
613 : SfxObjectShell(i_nSfxCreationFlags
)
614 , mpEditEngineItemPool(nullptr)
615 , mpEditEngine(nullptr)
617 , mpTmpPrinter(nullptr)
619 , mbFormulaArranged(false)
621 SvtLinguConfig().GetOptions(maLinguOptions
);
623 SetPool(&SfxGetpApp()->GetPool());
625 SmModule
*pp
= SM_MOD();
626 maFormat
= pp
->GetConfig()->GetStandardFormat();
628 StartListening(maFormat
);
629 StartListening(*pp
->GetConfig());
631 SetBaseModel(new SmModel(this));
634 SmDocShell::~SmDocShell()
636 SmModule
*pp
= SM_MOD();
638 EndListening(maFormat
);
639 EndListening(*pp
->GetConfig());
642 mpEditEngine
.reset();
643 SfxItemPool::Free(mpEditEngineItemPool
);
644 mpPrinter
.disposeAndClear();
647 bool SmDocShell::ConvertFrom(SfxMedium
&rMedium
)
649 bool bSuccess
= false;
650 const OUString
& rFltName
= rMedium
.GetFilter()->GetFilterName();
652 OSL_ENSURE( rFltName
!= STAROFFICE_XML
, "Wrong filter!");
654 if ( rFltName
== MATHML_XML
)
661 Reference
<css::frame::XModel
> xModel(GetModel());
662 SmXMLImportWrapper
aEquation(xModel
);
663 bSuccess
= ( ERRCODE_NONE
== aEquation
.Import(rMedium
) );
667 SvStream
*pStream
= rMedium
.GetInStream();
670 if ( SotStorage::IsStorageFile( pStream
) )
672 tools::SvRef
<SotStorage
> aStorage
= new SotStorage( pStream
, false );
673 if ( aStorage
->IsStream("Equation Native") )
675 // is this a MathType Storage?
676 OUStringBuffer aBuffer
;
677 MathType
aEquation(aBuffer
);
678 bSuccess
= aEquation
.Parse( aStorage
.get() );
681 maText
= aBuffer
.makeStringAndClear();
689 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
691 SetFormulaArranged( false );
700 bool SmDocShell::InitNew( const uno::Reference
< embed::XStorage
>& xStorage
)
703 if ( SfxObjectShell::InitNew( xStorage
) )
706 SetVisArea(tools::Rectangle(Point(0, 0), Size(2000, 1000)));
712 bool SmDocShell::Load( SfxMedium
& rMedium
)
715 if( SfxObjectShell::Load( rMedium
))
717 uno::Reference
< embed::XStorage
> xStorage
= GetMedium()->GetStorage();
718 uno::Reference
< container::XNameAccess
> xAccess (xStorage
, uno::UNO_QUERY
);
721 xAccess
->hasByName( "content.xml" ) &&
722 xStorage
->isStreamElement( "content.xml" )
725 xAccess
->hasByName( "Content.xml" ) &&
726 xStorage
->isStreamElement( "Content.xml" )
730 // is this a fabulous math package ?
731 Reference
<css::frame::XModel
> xModel(GetModel());
732 SmXMLImportWrapper
aEquation(xModel
);
733 auto nError
= aEquation
.Import(rMedium
);
734 bRet
= ERRCODE_NONE
== nError
;
739 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
741 SetFormulaArranged( false );
750 bool SmDocShell::Save()
752 //! apply latest changes if necessary
755 if ( SfxObjectShell::Save() )
762 Reference
<css::frame::XModel
> xModel(GetModel());
763 SmXMLExportWrapper
aEquation(xModel
);
764 aEquation
.SetFlat(false);
765 return aEquation
.Export(*GetMedium());
772 * replace bad characters that can not be saved. (#i74144)
774 void SmDocShell::ReplaceBadChars()
776 bool bReplace
= false;
780 OUStringBuffer
aBuf( mpEditEngine
->GetText() );
782 for (sal_Int32 i
= 0; i
< aBuf
.getLength(); ++i
)
784 if (aBuf
[i
] < ' ' && aBuf
[i
] != '\r' && aBuf
[i
] != '\n' && aBuf
[i
] != '\t')
792 maText
= aBuf
.makeStringAndClear();
797 void SmDocShell::UpdateText()
799 if (mpEditEngine
&& mpEditEngine
->IsModified())
801 OUString
aEngTxt( mpEditEngine
->GetText() );
802 if (GetText() != aEngTxt
)
808 bool SmDocShell::SaveAs( SfxMedium
& rMedium
)
812 //! apply latest changes if necessary
815 if ( SfxObjectShell::SaveAs( rMedium
) )
822 Reference
<css::frame::XModel
> xModel(GetModel());
823 SmXMLExportWrapper
aEquation(xModel
);
824 aEquation
.SetFlat(false);
825 bRet
= aEquation
.Export(rMedium
);
830 bool SmDocShell::ConvertTo( SfxMedium
&rMedium
)
833 std::shared_ptr
<const SfxFilter
> pFlt
= rMedium
.GetFilter();
841 const OUString
& rFltName
= pFlt
->GetFilterName();
842 if(rFltName
== STAROFFICE_XML
)
844 Reference
<css::frame::XModel
> xModel(GetModel());
845 SmXMLExportWrapper
aEquation(xModel
);
846 aEquation
.SetFlat(false);
847 bRet
= aEquation
.Export(rMedium
);
849 else if(rFltName
== MATHML_XML
)
851 Reference
<css::frame::XModel
> xModel(GetModel());
852 SmXMLExportWrapper
aEquation(xModel
);
853 aEquation
.SetFlat(true);
854 bRet
= aEquation
.Export(rMedium
);
856 else if (pFlt
->GetFilterName() == "MathType 3.x")
857 bRet
= WriteAsMathType3( rMedium
);
862 void SmDocShell::writeFormulaOoxml(
863 ::sax_fastparser::FSHelperPtr
const& pSerializer
,
864 oox::core::OoxmlVersion
const version
,
865 oox::drawingml::DocumentType
const documentType
)
871 SmOoxmlExport
aEquation(mpTree
.get(), version
, documentType
);
872 aEquation
.ConvertFromStarMath( pSerializer
);
875 void SmDocShell::writeFormulaRtf(OStringBuffer
& rBuffer
, rtl_TextEncoding nEncoding
)
881 SmRtfExport
aEquation(mpTree
.get());
882 aEquation
.ConvertFromStarMath(rBuffer
, nEncoding
);
885 void SmDocShell::readFormulaOoxml( oox::formulaimport::XmlStream
& stream
)
887 SmOoxmlImport
aEquation( stream
);
888 SetText( aEquation
.ConvertToStarMath());
891 void SmDocShell::Execute(SfxRequest
& rReq
)
893 switch (rReq
.GetSlot())
897 SmFormat aOldFormat
= GetFormat();
898 SmFormat
aNewFormat( aOldFormat
);
899 aNewFormat
.SetTextmode(!aOldFormat
.IsTextmode());
901 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
903 pTmpUndoMgr
->AddUndoAction(
904 new SmFormatAction(this, aOldFormat
, aNewFormat
));
906 SetFormat( aNewFormat
);
911 case SID_AUTO_REDRAW
:
913 SmModule
*pp
= SM_MOD();
914 bool bRedraw
= pp
->GetConfig()->IsAutoRedraw();
915 pp
->GetConfig()->SetAutoRedraw(!bRedraw
);
919 case SID_LOADSYMBOLS
:
923 case SID_SAVESYMBOLS
:
929 // get device used to retrieve the FontList
930 OutputDevice
*pDev
= GetPrinter();
931 if (!pDev
|| pDev
->GetDevFontCount() == 0)
932 pDev
= &SM_MOD()->GetDefaultVirtualDev();
933 OSL_ENSURE (pDev
, "device for font list missing" );
935 SmFontTypeDialog
aFontTypeDialog(rReq
.GetFrameWeld(), pDev
);
937 SmFormat aOldFormat
= GetFormat();
938 aFontTypeDialog
.ReadFrom( aOldFormat
);
939 if (aFontTypeDialog
.run() == RET_OK
)
941 SmFormat
aNewFormat( aOldFormat
);
943 aFontTypeDialog
.WriteTo(aNewFormat
);
944 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
946 pTmpUndoMgr
->AddUndoAction(
947 new SmFormatAction(this, aOldFormat
, aNewFormat
));
949 SetFormat( aNewFormat
);
957 SmFontSizeDialog
aFontSizeDialog(rReq
.GetFrameWeld());
959 SmFormat aOldFormat
= GetFormat();
960 aFontSizeDialog
.ReadFrom( aOldFormat
);
961 if (aFontSizeDialog
.run() == RET_OK
)
963 SmFormat
aNewFormat( aOldFormat
);
965 aFontSizeDialog
.WriteTo(aNewFormat
);
967 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
969 pTmpUndoMgr
->AddUndoAction(
970 new SmFormatAction(this, aOldFormat
, aNewFormat
));
972 SetFormat( aNewFormat
);
980 SmDistanceDialog
aDistanceDialog(rReq
.GetFrameWeld());
982 SmFormat aOldFormat
= GetFormat();
983 aDistanceDialog
.ReadFrom( aOldFormat
);
984 if (aDistanceDialog
.run() == RET_OK
)
986 SmFormat
aNewFormat( aOldFormat
);
988 aDistanceDialog
.WriteTo(aNewFormat
);
990 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
992 pTmpUndoMgr
->AddUndoAction(
993 new SmFormatAction(this, aOldFormat
, aNewFormat
));
995 SetFormat( aNewFormat
);
1003 SmAlignDialog
aAlignDialog(rReq
.GetFrameWeld());
1005 SmFormat aOldFormat
= GetFormat();
1006 aAlignDialog
.ReadFrom( aOldFormat
);
1007 if (aAlignDialog
.run() == RET_OK
)
1009 SmFormat
aNewFormat( aOldFormat
);
1011 aAlignDialog
.WriteTo(aNewFormat
);
1013 SmModule
*pp
= SM_MOD();
1014 SmFormat
aFmt( pp
->GetConfig()->GetStandardFormat() );
1015 aAlignDialog
.WriteTo( aFmt
);
1016 pp
->GetConfig()->SetStandardFormat( aFmt
);
1018 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
1020 pTmpUndoMgr
->AddUndoAction(
1021 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1023 SetFormat( aNewFormat
);
1031 const SfxStringItem
& rItem
= static_cast<const SfxStringItem
&>(rReq
.GetArgs()->Get(SID_TEXT
));
1032 if (GetText() != rItem
.GetValue())
1033 SetText(rItem
.GetValue());
1040 ::svl::IUndoManager
* pTmpUndoMgr
= GetUndoManager();
1043 sal_uInt16 nId
= rReq
.GetSlot(), nCnt
= 1;
1044 const SfxItemSet
* pArgs
= rReq
.GetArgs();
1045 const SfxPoolItem
* pItem
;
1046 if( pArgs
&& SfxItemState::SET
== pArgs
->GetItemState( nId
, false, &pItem
))
1047 nCnt
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
1049 bool (::svl::IUndoManager:: *fnDo
)();
1052 if( SID_UNDO
== rReq
.GetSlot() )
1054 nCount
= pTmpUndoMgr
->GetUndoActionCount();
1055 fnDo
= &::svl::IUndoManager::Undo
;
1059 nCount
= pTmpUndoMgr
->GetRedoActionCount();
1060 fnDo
= &::svl::IUndoManager::Redo
;
1065 for( ; nCnt
&& nCount
; --nCnt
, --nCount
)
1066 (pTmpUndoMgr
->*fnDo
)();
1068 catch( const Exception
& )
1070 DBG_UNHANDLED_EXCEPTION("starmath");
1075 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1078 SfxBindings
& rBind
= pFrm
->GetBindings();
1079 rBind
.Invalidate(SID_UNDO
);
1080 rBind
.Invalidate(SID_REDO
);
1081 rBind
.Invalidate(SID_REPEAT
);
1082 rBind
.Invalidate(SID_CLEARHISTORY
);
1083 pFrm
= SfxViewFrame::GetNext( *pFrm
, this );
1093 void SmDocShell::GetState(SfxItemSet
&rSet
)
1095 SfxWhichIter
aIter(rSet
);
1097 for (sal_uInt16 nWh
= aIter
.FirstWhich(); 0 != nWh
; nWh
= aIter
.NextWhich())
1102 rSet
.Put(SfxBoolItem(SID_TEXTMODE
, GetFormat().IsTextmode()));
1105 case SID_DOCTEMPLATE
:
1106 rSet
.DisableItem(SID_DOCTEMPLATE
);
1109 case SID_AUTO_REDRAW
:
1111 SmModule
*pp
= SM_MOD();
1112 bool bRedraw
= pp
->GetConfig()->IsAutoRedraw();
1114 rSet
.Put(SfxBoolItem(SID_AUTO_REDRAW
, bRedraw
));
1118 case SID_MODIFYSTATUS
:
1120 sal_Unicode cMod
= ' ';
1123 rSet
.Put(SfxStringItem(SID_MODIFYSTATUS
, OUString(cMod
)));
1128 rSet
.Put(SfxStringItem(SID_TEXT
, GetText()));
1132 //! very old (pre UNO) and ugly hack to invalidate the SmGraphicWindow.
1133 //! If mnModifyCount gets changed then the call below will implicitly notify
1134 //! SmGraphicController::StateChanged and there the window gets invalidated.
1135 //! Thus all the 'mnModifyCount++' before invalidating this slot.
1136 rSet
.Put(SfxInt16Item(SID_GAPHIC_SM
, mnModifyCount
));
1142 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1144 pFrm
->GetSlotState( nWh
, nullptr, &rSet
);
1146 rSet
.DisableItem( nWh
);
1150 case SID_GETUNDOSTRINGS
:
1151 case SID_GETREDOSTRINGS
:
1153 ::svl::IUndoManager
* pTmpUndoMgr
= GetUndoManager();
1156 OUString(::svl::IUndoManager:: *fnGetComment
)( size_t, bool const ) const;
1159 if( SID_GETUNDOSTRINGS
== nWh
)
1161 nCount
= pTmpUndoMgr
->GetUndoActionCount();
1162 fnGetComment
= &::svl::IUndoManager::GetUndoActionComment
;
1166 nCount
= pTmpUndoMgr
->GetRedoActionCount();
1167 fnGetComment
= &::svl::IUndoManager::GetRedoActionComment
;
1171 OUStringBuffer aBuf
;
1172 for (size_t n
= 0; n
< nCount
; ++n
)
1174 aBuf
.append((pTmpUndoMgr
->*fnGetComment
)( n
, ::svl::IUndoManager::TopLevel
));
1178 SfxStringListItem
aItem( nWh
);
1179 aItem
.SetString( aBuf
.makeStringAndClear() );
1184 rSet
.DisableItem( nWh
);
1192 ::svl::IUndoManager
*SmDocShell::GetUndoManager()
1196 return &mpEditEngine
->GetUndoManager();
1200 void SmDocShell::SaveSymbols()
1202 SmModule
*pp
= SM_MOD();
1203 pp
->GetSymbolManager().Save();
1207 void SmDocShell::Draw(OutputDevice
*pDevice
,
1209 sal_uInt16
/*nAspect*/)
1211 pDevice
->IntersectClipRegion(GetVisArea());
1213 DrawFormula(*pDevice
, atmppoint
);
1216 SfxItemPool
& SmDocShell::GetPool()
1218 return SfxGetpApp()->GetPool();
1221 void SmDocShell::SetVisArea(const tools::Rectangle
& rVisArea
)
1223 tools::Rectangle
aNewRect(rVisArea
);
1225 aNewRect
.SetPos(Point());
1227 if (! aNewRect
.Right()) aNewRect
.SetRight( 2000 );
1228 if (! aNewRect
.Bottom()) aNewRect
.SetBottom( 1000 );
1230 bool bIsEnabled
= IsEnableSetModified();
1232 EnableSetModified( false );
1234 //TODO/LATER: it's unclear how this interacts with the SFX code
1235 // If outplace editing, then don't resize the OutplaceWindow. But the
1236 // ObjectShell has to resize.
1238 if( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
&& !IsInPlaceActive() && GetFrame() )
1240 GetFrame()->LockAdjustPosSizePixel();
1241 bUnLockFrame
= true;
1244 bUnLockFrame
= false;
1246 SfxObjectShell::SetVisArea( aNewRect
);
1249 GetFrame()->UnlockAdjustPosSizePixel();
1252 EnableSetModified( bIsEnabled
);
1256 void SmDocShell::FillClass(SvGlobalName
* pClassName
,
1257 SotClipboardFormatId
* pFormat
,
1258 OUString
* /*pAppName*/,
1259 OUString
* pFullTypeName
,
1260 OUString
* pShortTypeName
,
1261 sal_Int32 nFileFormat
,
1262 bool bTemplate
/* = false */) const
1264 if (nFileFormat
== SOFFICE_FILEFORMAT_60
)
1266 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1267 *pFormat
= SotClipboardFormatId::STARMATH_60
;
1268 *pFullTypeName
= SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
);
1269 *pShortTypeName
= SmResId(RID_DOCUMENTSTR
);
1271 else if (nFileFormat
== SOFFICE_FILEFORMAT_8
)
1273 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1274 *pFormat
= bTemplate
? SotClipboardFormatId::STARMATH_8_TEMPLATE
: SotClipboardFormatId::STARMATH_8
;
1275 *pFullTypeName
= SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
);
1276 *pShortTypeName
= SmResId(RID_DOCUMENTSTR
);
1280 void SmDocShell::SetModified(bool bModified
)
1282 if( IsEnableSetModified() )
1284 SfxObjectShell::SetModified( bModified
);
1285 Broadcast(SfxHint(SfxHintId::DocChanged
));
1289 bool SmDocShell::WriteAsMathType3( SfxMedium
& rMedium
)
1291 OUStringBuffer
aTextAsBuffer(maText
);
1292 MathType
aEquation(aTextAsBuffer
, mpTree
.get());
1293 return aEquation
.ConvertFromStarMath( rMedium
);
1296 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */